La implementación subyacente del uso compartido de datos del proveedor para la gestión del estado de Flutter

Introducción

Los ingenieros senior de Flutter a menudo comienzan a investigar y aprender de la arquitectura más simple.

Lo que les traigo hoy es el proveedor de marco de administración de estado más importante en Flutter, y también es un marco que todo desarrollador de Flutter debe aprender. El proveedor es relativamente poderoso y puede implementar fácilmente funciones como cambio de idioma y cambio de idioma con un solo clic. Este artículo te enseñará cómo implementar paso a paso el framework Provider más simple para los estudiantes que no saben cómo guardarlo rápido y aprender despacio.

Diagrama de estructura del marco

inserte la descripción de la imagen aquí

Análisis de principios

Antes de explicar Provider, los lectores deben comprender las funciones de InheritedWidget y ChangeNotifier proporcionadas de forma nativa por Flutter para comprender verdaderamente el mecanismo de datos compartidos de Provider.

El papel de InheritedWidget

InheritedWidget es un importante componente de Widget proporcionado por Flutter. Brinda la capacidad de compartir datos de arriba a abajo en el árbol de Widget. Cuando InheritedWidget se usa como Widget principal, todos sus Widgets secundarios internos pueden acceder a los datos guardados en el Widget principal. .

Los ejemplos son los siguientes:

  1. Defina un ShareWidget heredado de InheritedWidget , que define un dato para guardar datos compartidos. Su código ShareWidget es el siguiente:
class ShareWidget extends InheritedWidget{
    
    
  const ShareWidget({
    
    super.key, required super.child,required this.data});
  final int data; //在子树中共享的数据

  
 //定义静态方法,数据共享给子Widget使用
  static ShareWidget? of(BuildContext context){
    
    
  //调用子控件的didChangeDependencies和rebuild方法
    return context.dependOnInheritedWidgetOfExactType<ShareWidget>();
  }
  //当回调决定当data发生变化时,通知子widget中使用date数据的widget执行build构建。
  @override
  bool updateShouldNotify(covariant ShareWidget oldWidget) {
    
    
    //当新旧数据发生变化时,通知子Widget重新构建
    return oldWidget.data != data;
  }

}

  1. El widget secundario accede a los datos compartidos en ShareWidget a través del método ShareWidget.of . Cuando los datos cambien, se notificará al sub-Widget para que se reconstruya, y se llamará internamente al método setState(){} del sub-Widget.

El papel de ChangeNotifier

Creo que todos los estudiantes están familiarizados con este modo de suscripción de EventBus en Android Flutter nos proporciona ChangeNotifier para implementar el modo de suscripción. Solo necesita heredar ChangeNotifier para realizar el monitoreo de datos. Echemos un vistazo al código fuente interno de ChangeNotifier .

class ChangeNotifier implements Listenable {
    
    
  List listeners=[];
  @override
  void addListener(VoidCallback listener) {
    
    
     //添加监听器
     listeners.add(listener);
  }
  @override
  void removeListener(VoidCallback listener) {
    
    
    //移除监听器
    listeners.remove(listener);
  }
  
  void notifyListeners() {
    
    
    //通知所有监听器,触发监听器回调 
    listeners.forEach((item)=>item());
  }
....
}

ChangeNotifier hereda de Listenable e internamente proporciona tres métodos: addListener, removeListener y notificarListeners . Este es un modelo de suscriptor típico.

Implementación del código del proveedor

  1. Defina la clase InheritedProvider para heredar de InheritedWidget . Los genéricos se pasan aquí. Facilita el intercambio de todos los tipos de datos.
class InheritedProvider<T> extends InheritedWidget{
    
    
  const InheritedProvider({
    
    super.key, required Widget child,
    required this.data}):super(child: child);
  ///需要共享的数据
  final T data;

  @override
  bool updateShouldNotify(covariant InheritedProvider<T> oldWidget) {
    
    
   //数据变化时通知子widget重建
   return oldWidget.data != data;
  }

}

  1. Defina ShopModel para heredar ChangeNotifier para proporcionar datos que deben compartirse. Aquí se define una colección de tipos int. Cuando se agregan los datos, se llama a applyListeners () para notificar a todos los suscriptores que actualicen los datos.
class ShopModel extends ChangeNotifier{
    
    
  final List<int> _items = [];
  List<int> get items =>_items;
  int get totalCount =>_items.fold<int>(0, (value, element)=>value+element);
  ///添加数据后,通知所有订阅者
  void addShop(int num){
    
    
    _items.add(num);
    notifyListeners();
  }

}

  1. El ChangeNotifierProvider personalizado se hereda de StatefulWidget Dado que ChangeNotifierProvider implica reconstruir el widget, debe heredar StatefulWidget con estado.
class ChangeNotifierProvider<T extends ChangeNotifier> extends StatefulWidget{
    
    
  const ChangeNotifierProvider({
    
    super.key, required this.data, required this.child});
  final Widget child;
  final T data;


  static T of<T>(BuildContext context){
    
    
    var provider =context.dependOnInheritedWidgetOfExactType<InheritedProvider<T>>();
    return provider!.data;
  }
   @override
  State<ChangeNotifierProvider<T>> createState() =>_ChangeNotifierProviderState<T>();
}

El método estático de se proporciona en ChangeNotifierProvider para proporcionar sub-Widgets para obtener datos compartidos T, donde T se refiere al ShopModel.

class _ChangeNotifierProviderState<T extends ChangeNotifier> extends State<ChangeNotifierProvider<T>>{
    
    
  ///更新重新构建wiget
  void update(){
    
    
    setState(() {
    
    
    });
  }
  @override
  void didUpdateWidget(covariant ChangeNotifierProvider<T> oldWidget) {
    
    
    if(oldWidget.data != widget.data){
    
    
       oldWidget.data.removeListener(update);
       widget.data.addListener(update);
     }
    super.didUpdateWidget(oldWidget);
  }
  @override
  void initState() {
    
    
    ///注册监听
    widget.data.addListener(update);
    super.initState();
  }
  @override
  void dispose() {
    
    
     ///移除监听
    widget.data.removeListener(update);
    super.dispose();
  }
  @override
  Widget build(BuildContext context) {
    
    
    ///这里使用InheritedProvider作为父widget,共享数据给子widget
    return InheritedProvider<T>(data: widget.data, child: widget.child);
  }

}

El monitoreo de datos de datos se registra en _ChangeNotifierProviderState. Este artículo hace referencia a ShopModel. Cuando ShopModel cambia, se notifica a todos los oyentes llamando al método notificarListeners() en ShopModel. Llame al método de actualización en _ChangeNotifierProviderState, el método de actualización llama a setState(){} y llama al método de reconstrucción del Widget actual para reconstruir. _ChangeNotifierProviderState usa InheritedProvider como widget principal para compartir datos, es decir, ShopModel con el widget secundario.

  1. Veamos el uso final.
ChangeNotifierProvider<CarModel>(
  data: ShopModel(),
  child: Builder(builder: (context) {
    
    
      return Center(child: Column(
        crossAxisAlignment: CrossAxisAlignment.center,
        children: [
          Builder(builder: (context) {
    
    
            var cart =
              ChangeNotifierProvider.of<ShopModel>(context);
            return Text("计算结果:${cart.totalCount}");
          }),
          const SizedBox(
            height: 40,
          ),
          ElevatedButton(
            onPressed: () {
    
    
                ChangeNotifierProvider.of<CarModel>(context)
                  .addShop(10);
              },
            child: const Text('增加数字'))
        ],
      ),);
    }))

Cuando hacemos clic en el botón Agregar número, el ShopModel devuelto por ChangeNotifierProvider.of(context) llama al método addShop de ShopModel y addShop llama a notificarListeners, que se reconstruye a través del oyente ChangeNotifierProvider para mostrar los datos más recientes.

Resumir

InheritedWidget, ChangeNotifier y Provider se usan ampliamente en Flutter y son relativamente importantes. También son componentes que los desarrolladores de Flutter deben aprender a usar. Además de estos componentes que pueden compartir datos, también existen excelentes marcos de trabajo de terceros como Bloc que los lectores necesitan estudiar y aprender por sí mismos. Comprender la idea de la implementación del marco y aprender a construir el marco. El objetivo de este artículo no es escribir código, sino implementar un marco excelente basado en componentes existentes, que es lo que persigue el editor.

por fin

Si desea convertirse en arquitecto o quiere superar el rango de salario de 20-30K, entonces no se limite a la codificación y los negocios, sino que debe poder seleccionar modelos, expandir y mejorar el pensamiento de programación. Además, un buen plan de carrera también es muy importante, y el hábito de aprender es muy importante, pero lo más importante es poder perseverar, cualquier plan que no se pueda implementar de manera constante es una palabrería.

Si no tiene una dirección, aquí me gustaría compartir con usted un conjunto de "Notas avanzadas sobre los ocho módulos principales de Android" escrito por el arquitecto principal de Ali, para ayudarlo a organizar el conocimiento desordenado, disperso y fragmentado de manera sistemática, para que que puede dominar de manera sistemática y eficiente los diversos puntos de conocimiento del desarrollo de Android.
imagen
En comparación con el contenido fragmentado que solemos leer, los puntos de conocimiento de esta nota son más sistemáticos, más fáciles de entender y recordar, y están organizados estrictamente de acuerdo con el sistema de conocimiento.

Bienvenidos a todos a apoyar con un clic y tres enlaces. Si necesita la información en el artículo, puede escanear directamente la tarjeta WeChat de certificación oficial de CSDN al final del artículo para obtenerla gratis ↓↓↓ PD: También hay

un Robot ChatGPT en el grupo, que puede responder a su trabajo o preguntas técnicas
imagen

Supongo que te gusta

Origin blog.csdn.net/datian1234/article/details/131947380
Recomendado
Clasificación