状态管理-Provider(一)

1.概述

provide是一个状态管理管理包,不是Google推出,但Provider是Google极力推荐的状态管理方式之一,它是对InheritedWidget组件进行了封装。
RenderObject树的重新渲染最原始的做法就是调用SetState方法,而Provider可以让你注重于数据逻辑的的改变,而无需关心RenderObject树的主动渲染,这不就是类似于mvvm模式,只要数据变化了,view树就会重新渲染该渲染的部分,而不需要咱们主动调用渲染。

  • Flutter三棵树:
    1)Widget:存放渲染内容、视图布局信息。
    2)Element:存放上下文,通过Element遍历视图树,Element同时持有Widget和RenderObject。
    3)RenderObject:根据Widget的布局属性进行layout,paint Widget传入的内容。

  • 在学习之前需要掌握InheritedWidget的使用和ChangeNotifier的使用。

2.Provider优势
  • 简化的资源分配与处置。
  • 懒加载。
  • 创建新类时减少大量的模板代码。
  • 支持 DevTools* 更通用的调用 InheritedWidget 的方式
  • 提升类的可扩展性,整体的监听架构时间复杂度以指数级增长(如 ChangeNotifier, 其复杂度为 O(N))。
3.Provider类说明
  • Nested组件
    Nested: 简化树结构嵌套过深
    SingleChildWidget: 单个子组件的组件,但是它与ProxyWidget不同,有一个build方法。
    SingleChildStatelessWidget: 它是一个实现SingleChildWidget的StatelessWidget,必须使用buildWithChild构建子组件
    SingleChildStatefulWidget: 它是一个实现SingleChildWidget的StatefulWidget,是与Nested兼容的StatefulWidget
  • Provider组件
    Provider组件分为四大类,分别如下:
    1).Nested系列
    MultiProvider: 主要作用是提高代码可读性和减少重复代码,是将多个提供者合并成单个线性的组件提供者。
    2).SingleChildStatefulWidget系列
    Selector0: 它是Selector至Selector6的基类
    Selector1-6: 它们是将Selector0与Provider.of结合使用的语法糖,继承自Selector0.
    3).SingleChildStatelessWidget系列
    Consumer1-6: 消费者,只是调用了Provider.of,主要作用是从顶层获取Provider<T>并将其值传递给了builder。
    InheritedProvider: InheritedWidget的通用实现,并且所有的继承自该类的都可以通过Provider.of来获取value
    DeferredInheritedProvider: InheritedProvider的子类,用于监听流或者接收一个Future
    StreamProvider: 监听流,并暴露出当前的最新值。
    FutureProvider: 接收一个 Future,并在其进入 complete 状态时更新依赖它的组件。
    ListenableProvider: 供可监听对象使用的特殊 provider,ListenableProvider 会监听对象,并在监听器被调用时更新依赖此对象的widgets。
    ChangeNotifierProvider: 为 ChangeNotifier 提供的 ListenableProvider规范,会在需要时自动调用 ChangeNotifier.dispose。
    ListenableProxyProvider0: 可见的代理提供者,主要是从其他提供者获取值。
    ListenableProxyProvider1-6: 它是ListenableProvider的一个变体,继承ListenableProxyProvider0, 从其他提供者获取值
    ChangeNotifierProxyProvider0: 主要用于构建和同步ChangeNotifier的ChangeNotifierProvider。
    Provider: 最基础的 provider 组成,接收一个任意值并暴露它。
    ProxyProvider0: 它公开的值会通过创建或更新构建,然后传递给 InheritedProvider。
    ProxyProvider1-6: ProxyProvider0的语法糖
  • InheritedContext系列
    InheritedContext: 与InheritedProvider关联的BuildContext,提供公开的值
    ReadContext: 公开读取方法
    SelectContext: 在 BuildContext 上添加一个选择方法。
    WatchContext: 公开 watch 方法。
Provider基本使用

首先定义一个类继承 ChangeNotifier

class CountNotifier with ChangeNotifier {
  int count = 0;
  void increment() {
    count++;
    notifyListeners();
  }
}

然后我们在MaterialApp之前对定义的共享数据进行了初始化

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return ChangeNotifierProvider(
      create: (_) => CountNotifier(),
      child: MaterialApp(
        debugShowCheckedModeBanner: false,
        home: SixDemo(),
      ),
    );
  }
}

最后一步通过Provider.of<CountNotifier>(context);获取到counter

import 'package:flutter/material.dart';
import 'package:provider/provider.dart';
import 'package:test_flutter/main.dart';
class SixDemo extends StatefulWidget {
  @override
  _SixDemoState createState() => _SixDemoState();
}

class _SixDemoState extends State<SixDemo> {

  @override
  Widget build(BuildContext context) {

    final counter = Provider.of<CountNotifier>(context);

    return Scaffold(
      appBar: AppBar(
        title: Text("InheritedWidget"),
      ),
      floatingActionButton: FloatingActionButton(
        onPressed: (){
          counter.increment();
        },
        child: Icon(Icons.add),
      ),
      body: Center(
        child: Text(counter.count.toString(),
          style: TextStyle(
              color: Colors.red,
              fontSize: 50
          ),
        ),
      ),
    );
  }
}
总结

以上是对Provider进行了介绍、优势、类结构和说明以及一个基本使用的例子,相对于使用InheritedWidget来说,显然Provider使用起来更简单。但是从它的提供者、消费者这些类来看稍微复杂,后面再分析。

©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

相关阅读更多精彩内容

友情链接更多精彩内容