美文网首页
状态管理-Provider

状态管理-Provider

作者: Jean_Lina | 来源:发表于2021-11-24 12:37 被阅读0次

provider:官方推荐的全局状态管理工具
使用之前,先在pubspec.yaml引入对它的依赖 provider: ^6.0.0
使用步骤:
(1)创建ChangeNotifier,真正数据(状态)存放的地方

class DBJHomeViewModel extends ChangeNotifier {
  int _counter = 890;

  int get counter => _counter;

  set counter(int value) {
    _counter = value;
    // 通知所有的依赖者进行更新
    notifyListeners();
  }

  DBJHomeViewModel(this._counter);
}

(2)在Widget Tree中插入ChangeNotifierProvider,Widget树中提供数据(状态)的地方,会在其中创建对应的ChangeNotifier。将ChangeNotifierProvider放到了顶层,这样方便在整个应用的任何地方可以使用共享数据

main() {
  runApp(
    ChangeNotifierProvider(
      child: DBJMyApp(),
      create: (cxt) => DBJHomeViewModel(209), //共享数据
    ),
  );
}

(3)使用共享数据

获取共享数据方法:
😊 Provider.of<T>(context);

😁 Consumer<T>

😊 Selector<A, S>

Widget build(BuildContext context) {
    print('_DBJContentWidgetState 执行build');
    return Scaffold(
      appBar: AppBar(
        title: Text('状态管理-Consumer'),
      ),
      body: Center(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: [
            DBJGoodsInfo(), //Provider 依赖数据展示
            SizedBox(height: 30),
            DBJShopCarInfo(), //Consumer 依赖数据展示
          ],
        ),
      ),
      floatingActionButton: buildFloatButtonWithConsumer(),
    );
  }
🍊 使用Consumer构建悬浮button:
  // 使用Consumer对共享数据进行修改
  Widget buildFloatButtonWithConsumer() {
    return Consumer<DBJHomeViewModel>(
      builder: (cxt, viewModel, child) {
        print('floatingActionButton Consumer 执行build');
        return FloatingActionButton(
          onPressed: () {
            print('点击++');
            //修改counter共享数据
            viewModel.counter++;
          },
          //直接引入Consumer的child,不进行新的构建
          child: child,
        );
      },
      child: Icon(Icons.inbox_rounded),
    );
  }
🍊 使用Selector构建悬浮button:
优化后:不依赖共享数据展示,只对共享数据进行修改
1:Provider.of<DBJHomeViewModel>(context, listen: false);
Widget buildFloatButtonWithProvider() {
    print('floatingActionButton 执行build');
    return FloatingActionButton(
      onPressed: () {
        print('点击++');
        DBJHomeViewModel viewModel =
        Provider.of<DBJHomeViewModel>(context, listen: false);
        viewModel.counter++; //修改counter共享数据
      },
      child: Icon(Icons.inbox_rounded),
    );
  }
2:使用Selector的shouldRebuild避免重复build
  Widget buildFloatButtonWithSelector() {
    return Selector<DBJHomeViewModel, DBJHomeViewModel>(
      selector: (cxc, viewModel) {
        return viewModel;
      },
      shouldRebuild: (previous, next) => false, // 不重新build
      child: Icon(Icons.inbox_rounded),
      builder: (BuildContext context, viewModel1, Widget? child) {
        print('floatingActionButton Selector 执行build');
        return FloatingActionButton(
          onPressed: () {
            print('点击++');
            viewModel1.counter++; //修改counter共享数据
          },
          child: child,
        );
      },
    );
  }
🍎 优化前(使用Provider获取数据,每次数据变化build方法重新执行)
class _DBJGoodsInfoState extends State<DBJGoodsInfo> {
  Widget buildWidgetWithProvider() {
    print('商品信息 执行build');
    int number = Provider.of<DBJHomeViewModel>(context).counter;
    return Card(
      child: Text(
        '商品信息:$number',
        style: TextStyle(fontSize: 18, color: Colors.purple),
      ),
    );
  }
🍎 优化后(使用Consumer获取数据减少build,每次数据变化仅Consumer内部的build方法重新执行)
  Widget buildWidgetWithConsumer() {
    print('商品信息 执行build');
    return Card(
      child: Consumer<DBJHomeViewModel>(
        builder: (BuildContext context, viewModel, Widget? child) {
          print('商品信息 Consumer 执行build');
          return Text(
            '商品信息:${viewModel.counter}',
            style: TextStyle(fontSize: 18, color: Colors.purple),
          );
        },
      ),
    );
  }
  @override
  Widget build(BuildContext context) {
    return buildWidgetWithProvider();
    return buildWidgetWithConsumer();
  }
}
🍎 最优方案(使用Selector,当viewModel中的其他数据发生变化,不依赖某个共享数据的其他widge,该build方法不会重新执行)
Widget buildPriceWidget() {
    print('价格信息 buildPriceWidget');
    return Selector<DBJHomeViewModel, DBJHomeViewModel>(
      selector: (cxt, vm) {
        return vm;
      },
      builder: (cxt, vm, child) {
        print('价格信息 Selector 执行build');
        return Container(
          child: Text(
            '价格信息:${vm.price}',
            style: TextStyle(fontSize: 18, color: Colors.green),
          ),
        );
      },
    );
  }
Simulator Screen Shot - iPhone 11 - 2021-11-24 at 12.15.56.png
截屏2021-11-24 下午12.16.06.png 12.png 截屏2021-11-24 下午3.04.28.png 截屏2021-11-24 下午3.03.25.png
截屏2021-11-24 下午3.23.02.png

相关文章

  • 状态管理-Provider

    provider:官方推荐的全局状态管理工具使用之前,先在pubspec.yaml引入对它的依赖 provider...

  • flutter使用Provider完成动态主题功能

    介绍 动态切换主题功能,使用Provider状态管理完成 学习本章内容,必须掌握Provider状态管理,如果有不...

  • Flutter 使用provider进行全局状态管理

    Flutter 使用provider进行全局状态管理 1. 导入provider 2. 创建一个provider ...

  • flutter 状态管理 Provider

    本文只简单介绍Provider的用法和使用中遇到的问题 2019 Google I/O 大会上,官方正式介绍了 由...

  • Flutter状态管理Provider

    链接:https://www.jianshu.com/p/93e97fd0f298 Google2019I/O大会...

  • Flutter状态管理-Provider

    在开发中经常会遇到状态管理的问题。一般原则是:如果状态跨组件共享,则该状态应该由各个组件共同的父元素来管理。目前已...

  • Flutter状态管理:Provider

    一、前言 此处系列章节目录,待更新 二、引入Provider第三方库 三、新增Model(CountProvide...

  • Flutter状态管理-provider

    什么是状态管理? 以下仅为本人浅见,如有不对请指出勿喷 状态管理就是一些变量的管理,而这些变量需要在多个 路由 界...

  • flutter provider管理状态

    自己稍微看了一下别人的然后稍微修改了一下建一个自定义的provider ,我用了demo里面的名字 上面是实例,下...

  • Flutter -- Provider 状态管理

    Provider 是一个用来提供数据的框架。它是 InheritedWidget 的语法糖,提供了依赖注入的功能,...

网友评论

      本文标题:状态管理-Provider

      本文链接:https://www.haomeiwen.com/subject/bwqgtrtx.html