第一步:添加依赖
在pubspec中添加scoped_model的依赖。
- 实际添加请参考:pub.dartlang.org/packages/sc…
- 由于版本冲突添加失败请参考:juejin.im/post/684490…
第二步:创建Model
在Scoped中,Model是一个只包含与状态相关信息的单位。我们应该把状态数据与操作数据的方法抽象出来封装到Model中。
import ‘package:scoped_model/scoped_model.dart’;
class CountModel extends Model{
int _count = 0;
get count => _count;
void increment(){
_count++;
notifyListeners();
}
}
- 我们需要让我们自定义的CountModel继承至Model。
- 在状态发生变化时(increment)通知所有用到了该model的子项更新状态。(notifyListeners)
第三步:将Model放入顶层
//创建顶层状态
CountModel countModel = CountModel();
@override
Widget build(BuildContext context) {
return ScopedModel(
model: countModel,
child: new MaterialApp(
home: TopScreen(),
),
);
}
- 我们在顶层创建了一个CountModel的实例。
- ScopedModel是一个StatelessWidget,它接收一个model,并提供给需要它的所有部件。
- 将ScopedModel的model属性绑定我们的CountModel对象。
第四步:在子页面中获取Model
我们可以从前面的演示图片中看出,一共有两个页面,都使用了同一个model。 Scoped_model提供了两种方式在子页面中获取model。我们先来介绍第一种,使用ScopedModelDescendant获取model。
@override
Widget build(BuildContext context) {
return ScopedModelDescendant(
builder: (context,child,model){
return Scaffold(
body: Center(
child: Text(
model.count.toString(),
style: TextStyle(fontSize: 48.0),
),
),
);
},
);
}
- ScopedModelDescendant是一个Stateless Widget,它接收三个参数。
- builder是一个ScopedModelDescendantBuilder,它接收三个参数。
,在builder中能够通过model来获取CountModel实例。
- rebuildOnChange属性能够控制当该状态发生变化时,是否rebuild,作用等同于setState。也就是说我们调用改变状态的一些方法时,不必再setState。
floatingActionButton: new FloatingActionButton(
onPressed: () => model.increment(),
tooltip: ‘Increment’,
child: new Icon(Icons.add),
)
第二种获取model的方式——使用ScopedModel.of
final countModel = ScopedModel.of(context);
countModel.increment();
或者在Model中重写of方法
class CountModel extends Model{
int _count = 0;
get count => _count;
void increment(){
_count++;
notifyListeners();
}
//重写of方法
CountModel of(context) =>
ScopedModel.of(context);
}
然后直接通过CountModel获取model实例
final countModel2 = CountModel().of(context);
这种方式似乎让我们的代码有更好的可阅读性。
【注意:】我们在使用第二种方式的时候,rebuildOnChange属性默认为false,所以会导致无法刷新(同步)状态的情况发生,需要手动指定rebuildOnChange:true。这里要非常感谢@荣毅coolboy同学的分享!
Q&A
这里看上去似乎只添加了一个model,我应该如何添加多个model
要解决这个问题很简单,使用Mixin!
class MainModel extends Model with AModel,BModel,CModel{}
然后将MainModel放在顶层即可。 这里有一个比较完整的使用ScopedModel管理状态的应用,详细用法可参考该项目。
Scoped是如何做到同步不同页面中的状态的
Model实现了Listenable接口,并重写了void addListener(VoidCallback listener),removeListener(VoidCallback listener)方法,实现了观察者模式。 每当我们调用notifyListeners()方法时,将会通知观察者更新状态。
Scoped如何做到数据能够互相共享的
最后我想说
为什么很多程序员做不了架构师?
1、良好健康的职业规划很重要,但大多数人都忽略了
2、学习的习惯很重要,持之以恒才是正解。
3、编程思维没能提升一个台阶,局限在了编码,业务,没考虑过选型、扩展
4、身边没有好的架构师引导、培养。所处的圈子对程序员的成长影响巨大。
金九银十面试季,跳槽季,整理面试题已经成了我多年的习惯!在这里我和身边一些朋友特意整理了一份快速进阶为Android高级工程师的系统且全面的学习资料。涵盖了Android初级——Android高级架构师进阶必备的一些学习技能。
附上:我们之前因为秋招收集的二十套一二线互联网公司Android面试真题(含BAT、小米、华为、美团、滴滴)和我自己整理Android复习笔记(包含Android基础知识点、Android扩展知识点、Android源码解析、设计模式汇总、Gradle知识点、常见算法题汇总。)
里面包含不同方向的自学编程路线、面试题集合/面经、及系列技术文章等,资源持续更新中…
《Android学习笔记总结+移动架构视频+大厂面试真题+项目实战源码》,点击传送门,即可获取!
g-h8cqlgWX-1714810255388)]
里面包含不同方向的自学编程路线、面试题集合/面经、及系列技术文章等,资源持续更新中…
《Android学习笔记总结+移动架构视频+大厂面试真题+项目实战源码》,点击传送门,即可获取!