Flutter 局部刷新/状态管理 全面总结 |
您所在的位置:网站首页 › flutter扫码传参 › Flutter 局部刷新/状态管理 全面总结 |
Flutter 局部刷新/ 状态管理
在Flutter中,如果我们想要更新页面中的某个widget的状态的话,一般会使用setState方法重走build方法来刷新。 //Flutter是描述性的(declarative), UI反映状态. UI = f(state)当页面布局复杂的时候,这样肯定是不行的。 这边梳理了下几种常见的方式,做个记录,方便将来选型 总体分为两类: 第一类,Dart 和 Flutter 内置支持 1. setState.Flutter里面最重要的方式 setState,规模较小的程序足够了,所有其它方式最终都需要调用 setState。 setState((){ _value = "new data"; }); 2. Function callback, 主要的实现有: ChangeNotifier, ValueNotifierValueNotifier 里面包含一个 T value 值,当值改变的时候,会通知它的监听来刷新UI //初始化 ValueNotifier indexNotifier = ValueNotifier(0); //数据变更: indexNotifier.value = value; //触发UI刷新 ValueListenableBuilder( valueListenable: indexNotifier, builder: (BuildContext context, int value, Widget child) { return CircleCheckBox( size: 40, activeColor: Color(periwinkle), value: _isSelect(value), onChanged: _onSelect, ); }, ) //销毁 indexNotifier.dispose();ValueNofiter 其实跟Android DataBinding 里面的 ObserverField 类似,都是使用一个观察者模式来实现数据驱动UI修改。 使用过程发现,这个类有个bug 当Value 是List是使用,修改数据不会发出通知,需要手动调用 notifyLisener(). 搜索了下,Flutter 项目下已经有这个issue了(https://github.com/flutter/flutter/issues/29958) 。 原因是因为,里面判断数据有变更的方法没有对List进行处理。 3. Global Key通信GlobalKey能够跨Widget访问状态,相比于Flutter的 函数声明式编程 类似 android等其他平台的命令式调用 //初始化: GlobalKey key = GlobalKey(); //使用: key.currentState.changeState(); 4. StreamBuilderStreamBuilder也是官方内置的一种刷新UI方式。数据封装成 流 通知UI变更 //步骤1:初始化一个StreamController final StreamController _streamController = StreamController(); //发送 _streamController.sink.add(_str); //UI 变更 child: StreamBuilder( // 监听Stream,每次值改变的时候,更新Text中的内容 stream: _streamController.stream, initialData: _str, builder: (BuildContext context, AsyncSnapshot snapshot){ return Text('点击的时候这个值会改变: ${snapshot.data}'); } ), // 销毁 _streamController.close(); 5. FutureBuilder通常用于是 异步编程,Future返回值是情况,它的构造方法: const FutureBuilder({ Key key, this.future, //获取数据的方法 this.initialData, //初始的默认数据 @required this.builder }) : assert(builder != null), super(key: key); 第二类,包-外部实现, 待完善 1. providerprovider 是 Google I/O 2019也推荐的状态管理库,网上内容也很多,源代码其实不多,很容易看懂。出自 Flutter dev team,绝对的官方了,总共代码 675行 Hilight里面也是用这个进行状态管理 实现: model类继承ChangeNotifer, class CounterModel extends ChangeNotifier { int value = 0; void increment() { value++; notifyListeners(); } void decrement() { value--; notifyListeners(); } } 数据提供者: ChangeNotifierProvider void main() => runApp(ChangeNotifierProvider( create: (context) => CounterModel(), child: MyApp(), )); 数据消费者/操纵者, 有两种方式: Consumer包裹, 用Provider.of. Consumer( builder: (context, counter, child) => Text( '${counter.value}', ), ),或者: FloatingActionButton( onPressed: () => Provider.of(context, listen: false).increment(), ),Provider性能相关的实现细节 Consumer包裹的范围要尽量小.Consumer中builder方法的第三个参数child 可以用于缓存一些并不需要重建的widget: return Consumer( builder: (context, cart, child) => Stack( children: [ // Use SomeExpensiveWidget here, without rebuilding every time. child, Text("Total price: ${cart.totalPrice}"), ], ), // Build the expensive widget here. child: SomeExpensiveWidget(), ); 2. scoped_model源自 Fuchsia 代码,包括注释也只有 287 行代码。 Scoped Model是基于InheritedWidget的. 思想仍然是把状态提到上层去, 并且封装了状态改变的通知部分。Provider 就是就是这个基础上 再新增 Providers,Provider 支持 Stream 3. InheritedWidget 4. Rxdux 5. Bloc 6. MobX 7.GetX2021 0708 重新回顾了下,发现这个库挺好用的。定点刷新比较简单。可以大力使用: flutter 一文带你了解GetX 原理 InheritedWidgetInheritedWidget的主要作用是在Widget树中有效地传递信息. Flutter中常用的Theme, Style, MediaQuery等就是inherited widget, 所以在程序里的各种地方都可以访问到它们. InheritedWidget也会用在其他状态管理模式中, 作为传递数据的方法. 当用InheritedWidget做状态管理时, 基本思想就是把状态提上去.当子widgets之间需要共享状态, 那么就把状态保存在它们共有的parent中 InheritedWidget解决了访问状态和根据状态更新的问题, 但是改变state却不太行. 参考: Flutter 应用性能优化最佳实践八种 Flutter 状态管理Flutter 状态管理Flutter State Management状态管理全面分析https://www.jianshu.com/p/f1fa7db28f7aFlutter局部刷新flutter局部刷新- GlobalKey数据监听Widget 自动更新你的UI划分组件,Flutter 改善套娃地狱问题 |
CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3 |