Casi toda aplicación necesita guardar datos. Algo típico es guardar las preferencias del usuario para que la próxima vez que arranque la aplicación, todo esté tal como estaba cuando entró la última vez. Por ejemplo, los colores, el lenguaje que prefiere, o incluso otros valores mas importantes como nombre de usuario y/o datos de login. Toda esta información debe permanecer almacenada para que la aplicación la vuelva a rescatar una vez que arranque de nuevo. ¿Cómo hacerlo en Flutter bajo GETX?

Existe un paquete estupendo llamado GET_STORAGE desarrollado por el mismo equipo que ha desarrollado GETX.

Te explico a continuación cómo usarlo para guardar las preferencias en una app.

Aplicación de ejemplo

Lo primero es instalar el paquete. Para ello, hemos de añadir la siguiente dependencia. Como vamos a trabajar en el entorno GetX también importaremos el paquete get.

dependencies:
  get_storage:
  get:

A continuación vamos a crear la clase MyPrefs que luego utilizaremos.

import 'package:flutter/material.dart';
import 'package:get/get.dart';
import 'package:get_storage/get_storage.dart';

class MyPrefs extends GetxController {

  final box = GetStorage(); // The info is saved to a file named GetStorage.gs

  // Other alternative is
  // final box = GetStorage('FileName'); // FileName will be the name for the data file used

  bool get isDark => box.read('darkmode') ?? false;
  ThemeData get theme => isDark ? ThemeData.dark() : ThemeData.light();
  void changeTheme(bool val) => box.write('darkmode', val);

  //get set for name1 value
  String get name1 => box.read('name1') ?? '';
  set name1 (String val) => box.write('name1', val);

  //get set for int1 value
  int get edad1 => box.read('edad1') ?? 0;
  set edad1 (int val) => box.write('edad1', val);

  //other way to do it name2 y edad2
  var name2 = ''.val('name2');
  var edad2 = 0.val('edad2');

  //other way to do it name3 y edad3
  var name3 = ReadWriteValue('name3', '');
  var edad3 = ReadWriteValue('edad3', 0);

  //final vars
  final mainTittle = 'Get_Storage with GetX Example App'.val('tittle');
}

Vamos a explicar un poco la clase anterior. Es una clase que extiende de GetxController porque vamos a utilizarla como controlador de un view. (Echa un vistazo a mis otros tutoriales sobre el uso de GetX como gestor de estados). En esta clase, lo primero es crear una instancia del GetStorage a la que llamamos box. Esta variable buscará un archivo en Documentos llamado GetStorage.ds. Si no existe lo creará. Si existe lo abrirá y leera los resultados.

Lo siguiente que hacemos es preparar algunas variables: isDark que es un bool que usaremos para guardar el modo gráfico seleccionado, luego un name1 name2 y name3 que almacenará un String que será el nombre del usuario, por último una variable tipo int llamadas edad1 edad2 y edad3 que guardarán números enteros.

Utilizamos varias maneras pero similares de usar las variables.

Además, tenemos un método get theme que devuelve un ThemeData dependiendo del tema seleccionado en el bool isDark, devolviendo el tema oscuro o el tema claro según proceda. Y además tenemos otro método llamado changeTheme que cambia el valor bool de la variable darkmode.

Vamos a crear ahora la clase main y la clase MyApp.

import 'package:flutter/material.dart';
import 'package:get/get.dart';
import 'package:get_storage/get_storage.dart';

void main() async {
  await GetStorage.init();
  runApp(MyApp());
}

En la clase main, lo primero que hemos de hacer es inicializar el GetStorage ántes de lanzar la app. Para ello utilizamos un async – await. Echa un vistazo a mis tutoriales sobre dart si no sabes cómo funcionan.

La clase MyApp quedará así:

import 'package:flutter/material.dart';
import 'package:get/get.dart';
import 'package:get_storage/get_storage.dart';

class MyApp extends StatelessWidget {
  const MyApp({Key? key}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    final preferences = Get.put(MyPrefs());
    return SimpleBuilder(builder: (_)
    {
      return MaterialApp(
        theme: preferences.theme,
        home: Scaffold(
          appBar: AppBar(title: Text(preferences.mainTittle.val)),
          body: Center(
            child: Column(
              mainAxisAlignment: MainAxisAlignment.center,
              children: [
                Text('Nombre 1: ${preferences.name1} Edad 1: ${preferences.edad1}'),
                Text('Nombre 2: ${preferences.name2.val} Edad 2: ${preferences.edad2.val}'),
                Text('Nombre 3: ${preferences.name3.val} Edad 3: ${preferences.edad3.val}'),
                const Divider(height: 5.0, color: Colors.amber,thickness: 5.0),
                SwitchListTile(
                    value: preferences.isDark,
                    title: const Text("Pulsa para cambiar el tema"),
                    onChanged: (_) {
                      //switch between dark and light themes
                      preferences.changeTheme(_);

                      //Test the variables name1 and edad1
                      if (preferences.name1 == 'Activo') {
                        preferences.name1 = 'No Activo';
                        preferences.edad1 = 12;
                      } else {
                        preferences.name1 = 'Activo';
                        preferences.edad1 = 7;
                      }

                      //Test the variables name2 and edad2
                      if (preferences.name2.val == 'Pedro') {
                        preferences.name2.val = 'Juan';
                        preferences.edad2.val = 25;
                      } else {
                        preferences.name2.val = 'Pedro';
                        preferences.edad2.val = 24;
                      }

                      //Test the varialbes name3 and edad 3
                      if (preferences.name3.val == '7ret') {
                        preferences.name3.val = 'CnkSoftware';
                        preferences.edad3.val = 12;
                      } else {
                        preferences.name3.val = '7ret';
                        preferences.edad3.val = 7;
                      }

                    }
                ),
              ],
            ),
          ),
        ),
      );
    });
  }
}

Vamos a explicar un poco la clase MyApp.

Lo primero que hacemos es inyectar el controlador que en nuestro caso es la clase MyPrefs. Para ello utilizamos un Get.put(MyPrefs()).

A continuación, utilizamos un SimpleBuilder (Que viene del paquete GetX) y que devuelve un simple StateFullWidget. Dentro de este, devolvemos un MaterialApp que es la base de nuestra app.

En el material App, creamos un Scaffold. La AppBar tendrá un título que mostrará las dos variables name1 y edad1 solo como referencia. El body tiene un center que incluye un SwitchListTile con el título ‘Pulsar para cambiar el Tema’. Este usa como valor la variable isDark de MyPrefs. Al cambiarlo, se dispara su evento onChanged y se envía el valor seleccionado. En su método actualizamos el valor de isDark mediante el método changeTheme de la clase MyPrefs y ahora jugamos un poco con las variables edad1 y name1 solo para ver cómo cambian también en la AppBar. Al actualizar el valor, el SimpleBuilder se redibuja nuevamente. Veremos como se alterna entre el tema oscuro y el tema claro.

Finalmente podemos eliminar una entrada o eliminar el fichero completo. Para ello:


//Remove name2 register from file
preferences.remove('name2');

//Remove the entire data file container
preferences.erase();

Para mas referencias sobre el uso del paquete GET_STORAGE te dejo el enlace a continuación:

https://pub.dev/packages/get_storage/example