Flutter: paquete de proveedor

El paquete del proveedor es un paquete fácil de usar que básicamente es un envoltorio alrededor de los widgets heredados que facilita su uso y administración. Proporciona una técnica de administración de estado que se utiliza para administrar una parte de los datos en la aplicación.

Las clases básicas disponibles en el paquete de proveedor son:

  • ChangeNotifierProvider<T extends ChangeNotifier> Escucha un ChangeNotifier extendido por la clase del modelo, lo expone a sus hijos y descendientes, y lo reconstruye depende cada vez que se llama a notificarListeners .
ChangeNotifierProvider(
  create: (context) => DataModel(),
  child: ...
)
  • Consumer<T> Obtiene el proveedor de sus ancestros y pasa el valor obtenido al constructor.
@override
 Widget build(BuildContext context) {
   return Consumer<DataModel>(
     builder: (context, data, child) => DataWidget(par1: par1, par2: par2),
     child: Text(data.first),
   );
 }
  • FutureProvider<T> Esta clase escucha un futuro y luego pasa sus valores a sus hijos y descendientes.
Constructors
FutureProvider<T>(
    {Key key,
    @required Create<Future<T>> create,
    T initialData,
    ErrorBuilder<T> catchError,
    UpdateShouldNotify<T> updateShouldNotify,
    bool lazy,
    TransitionBuilder builder,
    Widget child}
)
This creates a Future from create and subscribes to it.

FutureProvider.value(
    {Key key, 
    @required Future<T> value, 
    T initialData, 
    ErrorBuilder<T> catchError, 
    UpdateShouldNotify<T> updateShouldNotify, 
    TransitionBuilder builder, 
    Widget child}
    )
This constructor notifies the changed values to the FutureProvider children.

Ex: FutureProvider<Model>(create: (context) =>
 Model(),)
  • InheritedProvider<T> InheritedProvider proporciona una implementación general de InheritedWidget .
  • MultiProvider Un proveedor que se utiliza para proporcionar más de una clase al mismo tiempo.
MultiProvider(
  providers: [
    Provider<Model1>(create: (context) => Model1()),
    StreamProvider<Model2>(create: (context) => Model2()),
    FutureProvider<Model3>(create: (context) => Model3()),
  ],
  child: someWidget,
)
  • Provider<T> Es el proveedor básico.
  • ProxyProvider<T, R> El valor de este proveedor depende de otros proveedores. El valor puede ser utilizado por crear o actualizar.
Constructor
ProxyProvider(
    {Key key, 
    Create<R> create, 
    @required ProxyProviderBuilder<T, R> update, 
    UpdateShouldNotify<R> updateShouldNotify, 
    Dispose<R> dispose, bool lazy, 
    TransitionBuilder builder, 
    Widget child}
)
This initializes key for subclasses.
  • StreamProvider<T> Esta clase escucha un Stream y luego pasa sus valores a sus hijos y descendientes. Esto se puede utilizar como
Constructors
StreamProvider<T>(
    {Key key,
    @required Create<Stream<T>> create,
    T initialData,
    ErrorBuilder<T> catchError,
    UpdateShouldNotify<T> updateShouldNotify,
    bool lazy,
    TransitionBuilder builder,
    Widget child}
)
This creates a stream using create and subscribes to it.

StreamProvider.value(
    {Key key, 
    @required Stream<T> value, 
    T initialData, 
    ErrorBuilder<T> catchError, 
    UpdateShouldNotify<T> updateShouldNotify, 
    bool lazy, 
    TransitionBuilder builder, 
    Widget child}
)
This constructor notifies the changed values to the StreamProvider children.

Ex: StreamProvider<Model>(create: (context) =>
 Model(),)
  • ValueListenableProvider<T> Esta clase recibe cambios en el valor al suscribirse a un ValueListenable.
ValueListenableProvider<T>.value(
    {Key key,
    @required ValueListenable<T> value,
    UpdateShouldNotify<T> updateShouldNotify,
    TransitionBuilder builder,
    Widget child}
)
This constructor shows the changed values to its children.

Aparte de estos, hay una serie de otras clases que están disponibles según la necesidad, pero estas son las clases más utilizadas.

Para usar el paquete del proveedor, debemos agregar el paquete del proveedor a la sección de dependencias de pubspec.yaml y hacer clic en el botón Obtener para obtener las dependencias.

dependencies:
  flutter:
    sdk: flutter
  provider: ^4.3.2+4 #ADD

Veremos una aplicación de ejemplo simple

En primer lugar, definiremos una biblioteca modelo dentro de la carpeta lib que consta de item.dart y item_data.dart. Además de estos, la biblioteca tendrá 3 archivos dart más, a saber, main.dart, home.dart y item_list.dart. 

item.dart es una clase simple que define cuáles son los atributos que contendrá la clase de elemento y un método de alternancia.

Dart

import 'package:flutter/foundation.dart';
  
class Item {
  String item;
  bool completed;
  Item({@required this.item, this.completed = false});
  void toggle() {
    completed = !completed;
  }
}

item_data.dart contiene una lista que contendrá los datos de la clase Item definida anteriormente . Existen métodos para realizar tareas como agregar, alternar y eliminar un elemento de la lista.

Dart

import 'dart:collection';
import 'package:flutter/foundation.dart';
import '../model/item.dart';
  
class ItemData with ChangeNotifier {
  List<Item> _items = [];
  UnmodifiableListView<Item> get items => UnmodifiableListView(_items);
  
  get size => _items.length;
  
  void addItem(Item item) {
    _items.add(item);
    notifyListeners();
  }
  
  void toggleItem(Item item) {
    item.toggle();
    notifyListeners();
  }
  
  void removeItem(Item item) {
    _items.remove(item);
    notifyListeners();
  }
}

Ahora que el modelo está definido, limpiaremos main.dart como

Dart

import 'package:flutter/material.dart';
import 'package:provider/provider.dart';
import 'model/item_data.dart';
import 'home.dart';
  
void main() {
  runApp(MyApp());
}
  
class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return ChangeNotifierProvider(
      create: (context) => ItemData(),
      child: MaterialApp(
        debugShowCheckedModeBanner: false,
        title: 'Provider Demo',
        theme: ThemeData(
          primarySwatch: Colors.green,
        ),
        home: Home(),
      ),
    );
  }
}

El main.dart tiene un ChangeNotifierProvider que actúa como padre de la aplicación de material. Como nuestra aplicación es bastante pequeña, hemos definido el proveedor solo en la parte superior. En caso de que su aplicación sea bastante grande, puede colocar el proveedor en la parte superior del widget que necesita los datos y no en la parte superior.

item_list.dart crea un constructor ListView de los datos que provienen de la lista . Utiliza el Consumidor para obtener los datos.

Dart

import 'package:flutter/material.dart';
import 'package:provider/provider.dart';
import 'model/item_data.dart';
  
class ItemList extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Consumer<ItemData>(builder: (context, data, child) {
      return ListView.builder(
        scrollDirection: Axis.vertical,
        shrinkWrap: true,
        itemCount: data.size,
        itemBuilder: (context, index) {
          final item = data.items[index];
          return GestureDetector(
            onLongPress: () => data.removeItem(item),
            child: Container(
              padding: EdgeInsets.symmetric(vertical: 5),
              child: ListTile(
                leading: CircleAvatar(
                  backgroundColor: Colors.blueGrey,
                  child: Text(item.item[0]),
                ),
                title: Row(
                  mainAxisAlignment: MainAxisAlignment.spaceBetween,
                  children: [
                    Text(
                      item.item,
                      style: TextStyle(
                          decoration: item.completed
                              ? TextDecoration.lineThrough
                              : null,
                          fontSize: 16,
                          fontWeight: FontWeight.bold),
                    ),
                    Checkbox(
                      value: item.completed,
                      onChanged: (c) => data.toggleItem(item),
                    ),
                  ],
                ),
              ),
            ),
          );
        },
      );
    });
  }
}

Por último, escribiremos el código para el archivo home.dart que contiene los datos que se mostrarán en la pantalla. También contiene un TextField y un botón para agregar los datos a la lista.

Producción:

Además de Provider, también hay otros State Management disponibles, como:

  • StatefulWidget : estos son los widgets proporcionados en el paquete de material. Estos widgets tienen un estado interno que se puede reconstruir si la entrada cambia o si cambia el estado del widget.
  • InheritedWidget : estos son widgets simples que contienen los datos que deben usar sus hijos o descendientes. Estos proporcionan un mecanismo simple para mover datos a un niño mucho más abajo en el árbol de widgets. Hay un elemento asociado que cambia los datos cuando el elemento se actualiza. El paquete del proveedor es básicamente un envoltorio alrededor de InheritedWidgets.
  • ScopedModel : esta biblioteca se toma del código base de Fuchsia, que proporciona un método para pasar los datos de los padres a sus hijos. Cuando el modelo cambia, los niños se reconstruyen. Nuestra clase puede extender la clase Modelo para crear nuestros propios Modelos. ScopedModel Widget se envuelve alrededor del widget cuyos datos deben enviarse al árbol de widgets. ScopedModelDescendant Widget se usa para escuchar los cambios que ocurren en el modelo y reconstruir el elemento secundario.
  • BloC : C omponente Lógico de N egocio . Esta técnica nos permite manejar los datos como un Stream de eventos. Se encuentra entre la interfaz de usuario y los datos que manejan la lógica de la aplicación. Los componentes principales de BLoC son Sink y Stream . El StreamController maneja estos componentes. El sumidero se usa para agregar datos/eventos y el Stream se usa para escucharlos.

Publicación traducida automáticamente

Artículo escrito por muazzamfaraaz y traducido por Barcelona Geeks. The original can be accessed here. Licence: CCBY-SA

Deja una respuesta

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