(转)flutter 新状态管理方案 Provide (一)-使用
flutter 新状态管理方案 Provide (一)-使用
开这篇文章是因为看到这个库被托管在google的仓库下,而且说明是被设计出来替代ScopedModel的,而且更加灵活
支持Builder模式和StreamBuilder模式,全局,局部都可以
内部应该是结合InheritedWidget Notification体系实现的
传统的bloc需要在每一个Repository中创建StreamController和Stream,甚至有的文章中,一个监听的修改需要修改5处,维护起来比较麻烦
相比较而言Provide维护起来会稍微省事一些
添加依赖
dependencies:
provide: ^1.0.1 # 这里的版本查看官方
flutter packages get
import 'package:provide/provide.dart';
使用方法
这里以简单的Counter为例
也就是在flutter的hello world工程的基础上来修改
1. 定义一个Model
这个model需要继承ChangeNotifier
class Counter with ChangeNotifier {
int _value;
int get value => _value;
Counter(this._value);
void inc() {
_value++;
notifyListeners(); //父类的方法,发出通知
}
}
2. 定义一个全局的Provide
这里虽然定义在全局,但事实上也可以定义在页面级
void main() {
var providers = Providers()..provide(Provider.function((ctx) => Counter()));
runApp(
ProviderNode(
child: MyApp(),
providers: providers,
),
);
}
ProviderNode表示的是提供者
3. 界面/监听
修改_MyHomePageState
添加一个方法,用于获取Counter实例
Counter get _counter => Provide.value<Counter>(context);
将原来的Text(_counter)修改一下
这里的Provide会在Counter发生变化的时候,触发builder回调来更新界面
Provide<Counter>(
builder: (BuildContext context, Widget child, Counter counter) {
return Text(
'${counter.value}',
style: Theme.of(context).textTheme.display1,
);
},
),
4. 发出通知
接着就是发出通知了
修改floatingActionButton的点击事件
floatingActionButton: FloatingActionButton(
onPressed: () => _counter.inc(),
tooltip: 'Increment',
child: Icon(Icons.add),
),
这里调用第三步获取的那个Counter,然后调用inc方法
看到这里,如果之前用过ScopedModel的朋友会问了,这个不是和以前一样吗,我为啥要改呢
继续修改
5. Stream模式
这个就很类似于bloc了,只不过model不太一样
添加一个StreamBuilder
StreamBuilder<Counter>(
initialData: _counter,
stream: Provide.stream<Counter>(context),
builder: (BuildContext context, AsyncSnapshot<Counter> snapshot) {
return Text(
'${snapshot.data.value}',
style: Theme.of(context).textTheme.display1,
);
},
),
这里initialData是第三步创建的那个,stream是使用Provide.stream<Counter>(context)获取的
scope
在provide中有一个概念叫scope,类的完整类名叫ProviderScope
class ProviderScope {
final String _name;
/// Constructor
const ProviderScope(this._name);
@override
String toString() {
return "Scope ('$_name')";
}
}
这个类的作用就是标识Provider的区域,或者可以理解为给Provider/Provide定义一个作用区域
只有scope相同的才可以识别
将state的代码修改一下
class _MyHomePageState extends State<MyHomePage> {
Counter get _counter => Provide.value<Counter>(context);
PageCounter pageCounter = PageCounter();
PageCounter pageCounter2 = PageCounter();
var scope1 = ProviderScope("");
var scope2 = ProviderScope("");
@override
Widget build(BuildContext context) {
return ProviderNode(
providers: Providers()
..provide(Provider.value(pageCounter), scope: scope1)
..provide(Provider.value(pageCounter2), scope: scope2),
child: Scaffold(
appBar: AppBar(
title: Text(widget.title),
),
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Text(
'You have pushed the button this many times:',
),
Provide<PageCounter>(
scope: scope1,
builder:
(BuildContext context, Widget child, PageCounter counter) {
return Text(
'${counter.value}',
style: Theme.of(context).textTheme.display1,
);
},
),
Provide<PageCounter>(
scope: scope2,
builder:
(BuildContext context, Widget child, PageCounter counter) {
return Text(
'${counter.value}',
style: Theme.of(context).textTheme.display1,
);
},
),
StreamBuilder<Counter>(
initialData: _counter,
stream: Provide.stream<Counter>(context),
builder:
(BuildContext context, AsyncSnapshot<Counter> snapshot) {
return Text(
'${snapshot.data.value}',
style: Theme.of(context).textTheme.display1,
);
},
),
FlatButton(
child: Text("nextPage"),
onPressed: () {
Navigator.push(context,
MaterialPageRoute(builder: (BuildContext context) {
return MyHomePage(
title: "new page",
);
}));
},
),
],
),
),
floatingActionButton: FloatingActionButton(
onPressed: () {
_counter.inc();
pageCounter.inc();
pageCounter2.rec();
},
tooltip: 'Increment',
child: Icon(Icons.add),
),
),
);
}
}
这里定义了两个scope,并在Provide时进行了指定
Provide<PageCounter>(
scope: scope1,
builder:
(BuildContext context, Widget child, PageCounter counter) {
return Text(
'${counter.value}',
style: Theme.of(context).textTheme.display1,
);
},
),
这样只有当对应scope1的counter发出通知时,这里才会回调,这样就满足了一个页面/一个应用中有两个相同对象的识别问题
后记
这个插件托管在google仓库下,个人觉得应该是官方很推荐的一种状态管理模式
(转)flutter 新状态管理方案 Provide (一)-使用的更多相关文章
- 为了弄懂Flutter的状态管理, 我用10种方法改造了counter app
为了弄懂Flutter的状态管理, 我用10种方法改造了counter app 本文通过改造flutter的counter app, 展示不同的状态管理方法的用法. 可以直接去demo地址看代码: h ...
- vuex-- Vue.的中心化状态管理方案(vue 组件之间的通信简化机制)
vuex-- Vue.的中心化状态管理方案(vue 组件之间的通信简化机制) 如果你在使用 vue.js , 那么我想你可能会对 vue 组件之间的通信感到崩溃 .vuex就是为了解决组件通信问题的. ...
- 借鉴redux,实现一个react状态管理方案
react状态管理方案有很多,其中最简单的最常用的是redux. redux实现 redux做状态管理,是利用reducer和action实现的state的更新. 如果想要用redux,需要几个步骤 ...
- Redux/Mobx/Akita/Vuex对比 - 选择更适合低代码场景的状态管理方案
近期准备开发一个数据分析 SDK,定位是作为数据中台向外输出数据分析能力的载体,前端的功能表现类似低代码平台的各种拖拉拽.作为中台能力的载体,SDK 未来很大概率会需要支持多种视图层框架,比如Vue2 ...
- Flutter状态管理之provide和provider的使用区别
说道状态管理不得不说谷歌的亲自开发的两款状态管理Widget:第一个是provide,第二个是provider. 这两个的区别就是一个出来的早,现在好像没整么更新了.第二个是2019才出来的目前的版本 ...
- Flutter 对状态管理的认知与思考
前言 由 编程技术交流圣地[-Flutter群-] 发起的 状态管理研究小组,将就 状态管理 相关话题进行为期 两个月 的讨论. 目前只有内定的 5 个人参与讨论,如果你对 状态管理 有什么独特的见解 ...
- Flutter Bloc状态管理 简单上手
我们都知道,Flutter中Widget的状态控制了UI的更新,比如最常见的StatefulWidget,通过调用setState({})方法来刷新控件.那么其他类型的控件,比如StatelessWi ...
- Flutter 状态管理 flutter_Provide
项目的商品类别页面将大量的出现类和类中间的状态变化,这就需要状态管理.现在Flutter的状态管理方案很多,redux.bloc.state.Provide. Scoped Model : 最早的状态 ...
- React状态管理相关
关于React状态管理的一些想法 我最开始使用React的时候,那个时候版本还比较低(16版本以前),所以状态管理都是靠React自身API去进行管理,但当时最大的问题就是跨组件通信以及状态同步和状态 ...
随机推荐
- [随笔][Java][总结][java 类型系统]
java 的类型系统大体分为两类,对象和基本类型.java使用静态类型检查来保证类型安全.每个变量在使用之前需要声明.非静态类型的语言不要求变量在使用之前进行声明. 基本数据类型 java的基本类型不 ...
- Java高级特性 第7节 多线程
一.进程与线程的概念 1. 进程 进程是应用程序的执行实例,有独立的内存空间和系统资源. 如上图,标红色的是一个Office Word进程. 进程的特点: 动态性:进程是动态的创建和消亡: 并发性:操 ...
- C goto
http://c.biancheng.net/view/266.html 当程序遇到 goto 后, 会无条件跳转到标签后出,然后程序按照顺序执行 例子: #include <stdio.h&g ...
- Delphi 10.2.3
链接: https://pan.baidu.com/s/1Fy2LbcpmujOiqtNZ3ZySOQ 提取码: ts5k
- cannal&otter源码解析
一点引用资料的整理 http://www.tianshouzhi.com/api/tutorials/canal/381 canal 同步工具 https://github.com/alibaba/c ...
- h5交互动画如何制作
最近几年随着h5的兴起,复杂的h5动画,甚至是交互动画类型的产品不断涌现,尤其在课件产品方面,很多公司都有相关需求,最近很多h5开发工程师想了解相关方面的技术. 针对h5,如果是简单的动画效果,可以考 ...
- 导出dmp
如果有空表都需要导出执行 select 'alter table '||table_name||' allocate extent;' from user_tables where num_rows= ...
- python解决四舍五入问题
小数问题是计算机编程中大部分语言都会遇到的问题,尤其是在内容中涉及到评分.金额计算等等,本人一般在解决需求中固定小数位的数字计算时,都会先将其放大整10的倍数至整数,然后计算.存储,只有在显示的时候再 ...
- localStorage溢出问题
项目使用的store.js库 store.js库不能管理localStorage中的过期项到时清除,只能在再次调用get的时候才做处理,如果一直不调用get,过期了也还是占用着空间.溢出后,再储存项目 ...
- 2018-2019-2 20165312《网络攻防技术》Exp2 后门原理与实践
2018-2019-2 20165312<网络攻防技术>Exp2 后门原理与实践 课上知识点梳理总结 1.后门的概述 后门是指不经过正常认证流程而访问系统的通道 两个关键词:未认证.隐通道 ...