开发环境:
Mac OS 10.14.5
VSCode 1.36.1
Flutter 1.7.8+hotfix4
在 Flutter示例系列(一)中,每点击一次加号,则执行一次加1方法,并且调用 setState() 方法更新UI。
但是如果是一个大型应用,页面比较多,状态也比较多,有时还会出现多个页面共用同一个状态,此时页面刷新和状态管理略显复杂。所以需要 scoped_model 来替我们管理状态,显得更加方便。
scoped_model :父类向后代传递数据模型,每当数据模型更新,使用过模型的子类都会重建。
提供三个主要类:
在 Flutter示例系列(一)中,我们已创建好项目,现在我们稍作修改:
1.添加依赖
scoped_model: ^1.0.1
2.创建自己的CounterModel类
import 'package:scoped_model/scoped_model.dart';
class CounterModel extends Model {
int _counter = 0;
//get方法,获取_counter值
int get counter => _counter;
//每次调用,_counter 加1
void increment() {
_counter ++;
//通知所有的监听类,数据改变
notifyListeners();
}
}
3.修改main.dart文件
a)在 MyApp 类中,定义构造方法,参数是 CounterModel 类型,用于传递CounterModel对象
//自定义构造方法,@required 表明调用时必须有参数
const MyApp({Key key, @required this.model}) : super(key: key);
b)在 MyApp 类中,定义 CounterModel 类型的实例变量,用于接收从根widget处传递的model
//定义model变量
final CounterModel model;
c)在 MyApp 类中,build() 函数返回 ScopedModel 组件,并传递model
return ScopedModel (
model: model,
child: MaterialApp(
title: 'Scoped Model Demo',
home: MyHomePage(title: 'Scoped Model Demo'),
),
);
d)在MyHomePage中,修改类继承自StatelessWidget
class MyHomePage extends StatelessWidget
e)在MyHomePage中,利用ScopedModelDescendant获取model
ScopedModelDescendant (
//当model更新时调用
builder: (context, child, model){
return Text(
model.counter.toString(),
style: Theme.of(context).textTheme.display1,
);
},
)
或者这样获取
final counterModel = ScopedModel.of(context, rebuildOnChange: true);
如何在一个 build() 监听多个models?
比如我们不让AppModel包含了所有应用逻辑,而是分成UserModel、SearchModel、ProductModel等。
然而,我们需要在一个Widget中获取其中两个model,有两种选择:
1.用多个ScopedModelDescendant
2.用多个ScopedModel.of(),无需管理订阅,Flutter通过 InheritedWidgets去处理
class CombinedWidget extends StatelessWidget {
@override
Widget build(BuildContext context) {
final username =
ScopedModel.of(context, rebuildOnChange: true).username;
final counter =
ScopedModel.of(context, rebuildOnChange: true).counter;
return Text('$username tapped the button $counter times');
}
}
//注意:直接使用第二种时,rebuildOnChange设置非常重要!
至此,大致了解Scoped_model是如何集成项目中,但是一个成熟的项目,远比示例复杂,由浅及深,多查阅资料。
下一篇将会讲解fish-redux的用法。
本文Demo地址
碎碎念:
一开始觉得状态管理差不多也是redux_xxx之类,但是网上查阅之后,才知道原来有好几种管理方式,包含scoped_model、BLoC等。
大家也可以查看参考博文,原博主讲的更加详细(竖大拇指)。
scoped_model地址
参考博文
原始示例
=================================================================
个人博客
Github
个人公众号:Flutter小同学
个人网站