Cómo gestionar el estado en Flutter con Provider

Introducción

Índice
  1. Introducción
  • Prerrequisitos
  • Entendiendo el problema
  • Paso 1: Configuración del proyecto
  • Paso 2: Agregar el providercomplemento
  • Paso 3: Andamiaje del proyecto
  • Paso 4 — UsoProvider
  • Paso 5 — UsoChangeNotifier
  • Conclusión
  • La gestión del estado implica el seguimiento de los cambios de estado en toda la aplicación.

    El providerpaquete es una solución para las necesidades de gestión estatal.

    En este artículo, aprenderá cómo aplicar provideruna aplicación Flutter de muestra para administrar el estado de la información de la cuenta de usuario.

    Prerrequisitos

    Para completar este tutorial, necesitarás:

    • Para descargar e instalar Flutter .
    • Para descargar e instalar Android Studio o Visual Studio Code .
    • Se recomienda instalar complementos para su editor de código:
      • Fluttery Dartcomplementos instalados para Android Studio.
      • Flutterextensión instalada para Visual Studio Code.
    • La familiaridad con la navegación y las rutas será beneficiosa, pero no obligatoria.
    • La familiaridad con el estado del formulario también será beneficiosa, pero no es obligatoria.

    Este tutorial fue verificado con Flutter v2.0.6, Android SDK v31.0.2 y Android Studio v4.1.

    Entendiendo el problema

    Imagina una situación en la que quieres crear una aplicación que personaliza algunas de sus pantallas con algunos datos del usuario, como su nombre. Los métodos normales para pasar datos entre pantallas se convertirían rápidamente en un lío de devoluciones de llamadas, datos no utilizados y widgets reconstruidos innecesariamente. Con una biblioteca de interfaz como React, este es un problema común llamado prop boring .

    Si quisiéramos pasar datos desde cualquiera de esos widgets, entonces tendríamos que aumentar aún más cada widget intermedio con más devoluciones de llamadas sin usar. Para la mayoría de las funciones pequeñas, esto puede hacer que no valga la pena el esfuerzo.

    Afortunadamente para nosotros, el providerpaquete nos permite almacenar nuestros datos en un widget que está más arriba, como donde sea que inicialicemos nuestro MaterialApp, luego acceder a él y cambiarlo directamente desde los sub-widgets, independientemente de la anidación y sin reconstruir todo lo demás.

    Paso 1: Configuración del proyecto

    Una vez que haya configurado su entorno para Flutter, puede ejecutar lo siguiente para crear una nueva aplicación:

    1. flutter create flutter_provider_example

    Navegue hasta el nuevo directorio del proyecto:

    1. cd flutter_provider_example

    El uso flutter createproducirá una aplicación de demostración que mostrará la cantidad de veces que se hace clic en un botón.

    Paso 2: Agregar el providercomplemento

    A continuación, necesitaremos agregar el providercomplemento dentro de nuestro pubspec.yaml:

    archivo pubspec.yaml

    dependencies:  flutter:    sdk: flutter  provider: ^3.1.0

    Luego, guarde los cambios en su archivo.

    Nota: Si está utilizando VS Code, puede considerar usar la extensión Pubspec Assist para agregar dependencias rápidamente.

    Ahora podemos continuar y ejecutar esto en el simulador o dispositivo iOS o Android de su elección.

    Paso 3: Andamiaje del proyecto

    Necesitaremos dos pantallas, nuestro enrutador y una barra de navegación. Estamos configurando una página para mostrar los datos de nuestra cuenta y otra para actualizarla con el estado que se almacena, cambia y transmite desde nuestro enrutador.

    Abra main.dartsu editor de código y modifique las siguientes líneas de código:

    lib/main.dart

    import 'package:flutter/material.dart';import 'package:provider/provider.dart';import './screens/account.dart';import './screens/settings.dart';void main() {  runApp(MyApp());}class MyApp extends StatelessWidget {  @override  Widget build(BuildContext context) {    return MaterialApp(      title: 'Flutter Provider Demo',      home: MyHomePage(),    );  }}class MyHomePage extends StatefulWidget {  @override  _MyHomePageState createState() = _MyHomePageState();}class _MyHomePageState extends StateMyHomePage {  @override  Widget build(BuildContext context) {    return MaterialApp(home: AccountScreen(), routes: {      'account_screen': (context) = AccountScreen(),      'settings_screen': (context) = SettingsScreen(),    });  }}

    Crea un navbar.dartarchivo y ábrelo con tu editor de código:

    lib/navbar.dart

    import 'package:flutter/material.dart';import './screens/account.dart';import './screens/settings.dart';class Navbar extends StatelessWidget {  @override  Widget build(BuildContext context) {    return Container(      color: Colors.blue,      child: Row(        mainAxisAlignment: MainAxisAlignment.spaceAround,        children: Widget[          TextButton(            onPressed: () =              Navigator.pushReplacementNamed(context, AccountScreen.id),            child: Icon(Icons.account_circle, color: Colors.white)          ),          TextButton(            onPressed: () =              Navigator.pushReplacementNamed(context, SettingsScreen.id),            child: Icon(Icons.settings, color: Colors.white)          ),        ],      ),    );  }}

    En el libdirectorio, crea un nuevo screenssubdirectorio:

    1. mkdir lib/screens

    En este subdirectorio, crea un settings.dartarchivo. Este se utilizará para crear el estado de nuestro formulario, configurar un mapa para almacenar nuestras entradas y agregar un botón de envío que utilizaremos más adelante:

    lib/pantallas/configuraciones.dart

    import 'package:flutter/material.dart';import 'package:provider/provider.dart';import '../main.dart';import '../navbar.dart';class SettingsScreen extends StatelessWidget {  static const String id = 'settings_screen';  final formKey = GlobalKeyFormState();  final Map data = {'name': String, 'email': String, 'age': int};  @override  Widget build(BuildContext context) {    return Scaffold(      bottomNavigationBar: Navbar(),      appBar: AppBar(title: Text('Change Account Details')),      body: Center(        child: Container(        padding: EdgeInsets.symmetric(vertical: 20, horizontal: 30),        child: Form(          key: formKey,          child: Column(              mainAxisAlignment: MainAxisAlignment.center,              crossAxisAlignment: CrossAxisAlignment.center,              children: Widget[                TextFormField(                  decoration: InputDecoration(labelText: 'Name'),                  onSaved: (input) = data['name'] = input,                ),                TextFormField(                  decoration: InputDecoration(labelText: 'Email'),                  onSaved: (input) = data['email'] = input,                ),                TextFormField(                  decoration: InputDecoration(labelText: 'Age'),                  onSaved: (input) = data['age'] = input,                ),                TextButton(                  onPressed: () = formKey.currentState.save(),                  child: Text('Submit'),                  style: TextButton.styleFrom(                    primary: Colors.white,                    backgroundColor: Colors.blue,                  ),                )              ]            ),          ),        ),      ),    );  }}

    También en este subdirectorio, crea un account.dartarchivo que se utilizará para mostrar la información de la cuenta:

    lib/pantallas/cuenta.dart

    import 'package:flutter/material.dart';import 'package:provider/provider.dart';import '../main.dart';import '../navbar.dart';class AccountScreen extends StatelessWidget {  static const String id = 'account_screen';  @override  Widget build(BuildContext context) {    return Scaffold(      bottomNavigationBar: Navbar(),      appBar: AppBar(        title: Text('Account Details'),      ),      body: Center(        child: Column(          mainAxisAlignment: MainAxisAlignment.center,          children: Widget[            Text('Name: '),            Text('Email: '),            Text('Age: '),          ],        ),      ),    );  }}

    Compila tu código y ejecútalo en un emulador:

    En este punto, tienes una aplicación con una pantalla de Cuenta y una pantalla de Configuración.

    Paso 4 — UsoProvider

    Para configurar un testamento providerserá necesario envolver nuestro MaterialAppen un Providercon el tipo de nuestros datos.

    Vuelve a consultarlo main.darty ábrelo en tu editor de código. Para este tutorial, el tipo de datos es Map. Por último, debemos configurarlo createpara que luego usemos nuestro contexty data:

    lib/main.dart

    // ...class _MyHomePageState extends StateMyHomePage {  Map data = {    'name': 'Sammy Shark',    'email': 'example@example.com',    'age': 42  };  @override  Widget build(BuildContext context) {    return ProviderMap(      create: (context) = data,      child: MaterialApp(home: AccountScreen(), routes: {        'account_screen': (context) = AccountScreen(),        'settings_screen': (context) = SettingsScreen(),      }),    );  }}

    El datamapa ahora está disponible en todas las demás pantallas y widgets que main.dartllaman e importan el providerpaquete.

    Todo lo que le pasamos a nuestro Providercreador ahora está disponible en Provider.ofMap(context). Tenga en cuenta que el tipo que pasa debe coincidir con el tipo de datos que nuestro creador Providerespera.

    Nota: Si estás usando VS Code, quizás quieras considerar usar fragmentos , ya que probablemente accederás providera mucho:

    dardo.json

    "Provider": {  "prefix": "provider",  "body": [    "Provider.of$1(context).$2"  ]}

    Vuelve a consultarlo account.darty ábrelo en tu editor de código. Agrega las siguientes líneas de código:

    lib/pantallas/cuenta.dart

    // ...body: Center(  child: Column(    mainAxisAlignment: MainAxisAlignment.center,    children: Widget[      Text('Name: ' + Provider.ofMap(context)['name'].toString()),      Text('Email: ' + Provider.ofMap(context)['email'].toString()),      Text('Age: ' + Provider.ofMap(context)['age'].toString()),    ]),  ),)// ...

    Compila tu código y ejecútalo en un emulador:

    En este punto, tienes una aplicación con datos de usuario codificados que se muestran en la pantalla Cuenta.

    Paso 5 — UsoChangeNotifier

    Usar Providereste método parece muy descendente, ¿qué pasa si queremos pasar datos y modificar nuestro mapa? El método Providerpor sí solo no es suficiente para eso. Primero, necesitamos descomponer nuestros datos en su propia clase que extienda ChangeNotifier. Providerno funcionará con eso, por lo que necesitamos cambiarlo a ChangeNotifierProvidery pasar una instancia de nuestra Dataclase en su lugar.

    Ahora estamos pasando una clase completa y no solo una única variable, esto significa que podemos comenzar a crear métodos que pueden manipular nuestros datos, que también estarán disponibles para todo lo que acceda Provider.

    Después de cambiar cualquiera de nuestros datos globales que queramos usar notifyListeners, esto reconstruirá todos los widgets que dependen de él.

    Revisalo main.darty ábrelo en tu editor de código:

    lib/main.dart

    // ...class _MyHomePageState extends StateMyHomePage {  @override  Widget build(BuildContext context) {    return ChangeNotifierProviderData(      create: (context) = Data(),      child: MaterialApp(home: AccountScreen(), routes: {        'account_screen': (context) = AccountScreen(),        'settings_screen': (context) = SettingsScreen(),      }),    );  }}class Data extends ChangeNotifier {  Map data = {    'name': 'Sammy Shark',    'email': 'example@example.com',    'age': 42  };  void updateAccount(input) {    data = input;    notifyListeners();  }}

    Dado que cambiamos nuestro Providertipo, necesitamos actualizar nuestras llamadas a él. Vuelve a visitarlo account.darty ábrelo en tu editor de código:

    lib/pantallas/cuenta.dart

    // ...body: Center(  child: Column(    mainAxisAlignment: MainAxisAlignment.center,    children: Widget[      Text('Name: ' + Provider.ofData(context).data['name'].toString()),      Text('Email: ' + Provider.ofData(context).data['email'].toString()),      Text('Age: ' + Provider.ofData(context).data['age'].toString()),    ]),  ),)// ...

    Para pasar datos, necesitaremos acceder al Providermétodo que se pasó en la Dataclase. Vuelva a consultarlo settings.darty ábralo en su editor de código:

    lib/pantallas/configuraciones.dart

    TextButton(  onPressed: () {    formKey.currentState.save();    Provider.ofData(context, listen: false).updateAccount(data);    formKey.currentState.reset();  },)

    Compila tu código y ejecútalo en un emulador:

    En este punto, tienes una aplicación que admite la actualización de la información del usuario en la pantalla de Configuración y la visualización de los cambios en la pantalla de Cuenta.

    Conclusión

    En este artículo, aprendió cómo aplicar provideruna aplicación Flutter de muestra para administrar el estado de la información de la cuenta de usuario.

    Si desea obtener más información sobre Flutter, consulte nuestra página de temas de Flutter para ver ejercicios y proyectos de programación.

    SUSCRÍBETE A NUESTRO BOLETÍN 
    No te pierdas de nuestro contenido ni de ninguna de nuestras guías para que puedas avanzar en los juegos que más te gustan.

    Deja una respuesta

    Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *

    Subir

    Este sitio web utiliza cookies para mejorar tu experiencia mientras navegas por él. Este sitio web utiliza cookies para mejorar tu experiencia de usuario. Al continuar navegando, aceptas su uso. Mas informacion