目录
一、状态管理简介
1.1 为什么需要状态管理
1.1.1 Flutter与adr/ios UI框架区别
Flutter应用是 声明式(declarative)的框架,需要通过更新状态(state)来更新view。Android SDK 与 iOS UIKit是命令式(imperative)框架,可以获取view实例来更新view。 Flutter 构建的用户界面就是应用的当前状态。
比如 对于以下View变化的例子,Native可以直接 findViewById 获取到View实例,调用相关方法进行更改。 Flutter要改变 UI,Widget 会在自身上触发重建(在 Flutter 中最常见的方法是在 StatefulWidgets 组件上调用 setState())并构造一个新的 Widget 子树。
// Native命令式的(Imperative style)
b.setColor(red)
b.clearChildren()
ViewC c3 = new ViewC(...)
b.add(c3)
// Dart 声明式(Declarative style)
return ViewB(
color: red,
child: ViewC(...),
)
与Native view/UIView 相比Flutter widget 是不可变的,一旦需要变化则生命周期终止。任何时候 widget 或它们的状态变化时, Flutter 框架都会创建一个新的 widget 树的实例。
1.1.2 状态管理框架使用场景
需要自己管理的状态可以分为两种概念类型:短时 (ephemeral) 状态和应用 (app) 状态。
一个独立 widget 中需要,其他widget 树不需要的状态即为短时状态。可以不用状态管理框架。
如果需要应用中的多个部分之间共享一个非短时的状态,比如登陆信息,即需要状态管理框架。
1.2 需要解决的问题
1、通信:父子通信、兄弟通信
2、数据共享:全局状态共享、模块数据共享
3、解耦:view和logic解耦;view细化(解决setState 刷新粒度过大导致的性能损耗);逻辑分层,职责隔离;
4、单元测试:业务逻辑可测试
二、状态管理框架现有方案调研
2.1 状态管理框架
2.1.1 官方方案
1、InheritedWidget、Notification 、 EventBus
可以实现组件间的单向数据传递。
不适用场景:当需要共享的数据关系较多时,单向数据传递很难保持清晰的数据流动方向和顺序,导致应用内数据传递嵌套和回调混乱。
2、Provider
Provider 是flutter官方提供的状态管理库。基于Provider较容易实现MVVM。
库中的Provider组件基于InheritedWidget 实现,因此它也是一个 Widget。
可以用 Provider 来实现静态的数据读传递,也可以使用 ChangeNotifierProvider 来实现动态的数据读写传递,还可以通过 MultiProvider 来实现多个数据资源的共享。
Provider 可以基于 Consumer 精确地控制 UI 刷新粒度。
使用示例:
//声明Provider的提供者
ChangeNotifierProvider<LoginViewModel>.value(
notifier: LoginViewModel(),
child:LoginPage(),
)
/// login_page.dart
//创建provider对象
var loginVM = Provider.of<LoginViewModel>(context);
//使用
onPressed: () { loginVM.login()}
var isLoading = loginVM.isLoading;
//login_view_model.dart
class LoginViewModel extends ChangeNotifier{
bool isLoading = false;
login(){
isLoading = true;
LoginModel.login((LoginResult result)) {
isLoading = false;
notifyListeners();
}
}
}
2.2 市场方案调研
flutter_bloc | flutter_redux | fish_redux | |
简介 | Bloc模式的flutter实现。状态管理框架。 | Redux模式的Flutter实现。 状态管理框架。 | 闲鱼开源方案,基于 Redux 做状态管理的flutter应用框架 |
优/缺点 | 与Provider相似,可以使用BlocPrivider 实现MVVM。也可以使用bloc相关方法。 | 优点:UI代码组件化。 缺点:业务较复杂时,无法做到逻辑代码的分治和复用 | 优点:相比redux还解决了分治,通信,数据驱动,解耦等等问题。 缺点:概念繁多,接入复杂 |
适用场景 | 中复杂度模块 | 中复杂度模块 | 中大型的复杂应用 |
学习成本 | 中 | 中 | 高 |
使用项目 | dy_flutter,gsy | gsy | 闲鱼 |
2.2.1 flutter_bloc
BLoC(Business Logic Component)是一种设计模式,可以使业务逻辑和UI展示更好的区分。
Bloc makes it easy to separate presentation from business logic, making your code fast, easy to test, and reusable.
flutter_bloc是bloc的flutter实现,部分逻辑基于Provider实现。因此可以使用BlocProvider实现MVVM;也可以结合StringBuilder、StreamController/Rxdart实现流式管理;也可以使用state、event 、bloc实现bloc。
2.2.2 flutter_redux
redux模式的flutter实现。
2.2.3 fish_redux
基于redux的项目管理框架。