Flutter 局部刷新/状态管理 全面总结

您所在的位置:网站首页 flutter扫码传参 Flutter 局部刷新/状态管理 全面总结

Flutter 局部刷新/状态管理 全面总结

2024-07-14 20:02| 来源: 网络整理| 查看: 265

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, ValueNotifier

ValueNotifier 里面包含一个 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. StreamBuilder

StreamBuilder也是官方内置的一种刷新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. provider

provider 是 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.GetX

2021 0708 重新回顾了下,发现这个库挺好用的。定点刷新比较简单。可以大力使用: flutter 一文带你了解GetX

原理 InheritedWidget

InheritedWidget的主要作用是在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