大家好,我是学习Flutter好几个月的三须鳗鱼 张信哲 ,熟练使用CV大法。
这次记录的是跨组件共享插件:provider
参考资料:GitHub
provider的简单使用总共分为四步
在pubspec.yaml中引入,最新版本请访问:pub.dve
provider: ^4.3.2+2
参考:GitHub
class Counter with ChangeNotifier, DiagnosticableTreeMixin {
int _count = 0;
int get count => _count;
void increment() {
_count++;
notifyListeners();
}
/// Makes `Counter` readable inside the devtools by listing all of its properties
@override
void debugFillProperties(DiagnosticPropertiesBuilder properties) {
super.debugFillProperties(properties);
properties.add(IntProperty('count', count));
}
}
代码说明:
Counter
相当于Android MVP中的P,需要在其中实现具体业务。_count
是需要变更或处理的数据,可以定义为其他可用类型(比如网络请求返回组装的Bean)void increment()
是某一件事的具体实现方法,比如里边的:_count++;
notifyListeners()
是变更通知,在数据处理完成后执行void debugFillProperties
不知道啥意思,看着像是get方法的注册properties.add(IntProperty('count', count))
, count
方法返回的 _count
是int类型,所以这里使用IntProperty
,如果是其他类型,需要更换(我直接用ObjectFlagProperty
)实现一个稍微复杂点的业务(倒计时)
class Counter with ChangeNotifier, DiagnosticableTreeMixin{
List _time = ['获取验证码','1']; /// 处理的数据是个list,第一个是要显示的时间,第二个是倒计时状态
List get time => _time; /// 一个get方法
void timer(){ /// 在这里实现业务
//计时30秒
int totalTime = 30* 1000;
// 初始化设置
TimerUtil _timerUtil = new TimerUtil(mTotalTime: totalTime); /// TimerUtil 是本地的一个工具类
//设置计时回调 执行计时任务
//这里只是更新了一个 文本显示
_timerUtil.setOnTimerTickCallback((int tick) {
double _tick = tick / 1000;
_time[0] = _tick.toInt().toString() + 'S'; /// 每秒更新一次
_time[1] = '0';
if (_tick == 0) {
_time[1] = '1';
_time[0] = '获取验证码';
}
notifyListeners(); /// 通知更新
});
//开始倒计时
_timerUtil.startCountDown();
}
/// Makes `Counter` readable inside the devtools by listing all of its properties
@override
void debugFillProperties(DiagnosticPropertiesBuilder properties) {
super.debugFillProperties(properties);
properties.add(ObjectFlagProperty('time', time)); /// 注册方法? CV大法好
}
}
provider 需要在main中注册
原来的代码:
runApp( MyApp());
provider 需要的代码
runApp(
MultiProvider(
providers: [
ChangeNotifierProvider(create: (_) => Counter()),
],
child: const MyApp(),
),
);
providers: [ChangeNotifierProvider(create: (_) => Counter()), ]
部分可以提出来,单独写个list,在这里维护ChangeNotifierProvider
List<SingleChildWidget> providers = [
ChangeNotifierProvider(create: (_) => Counter()),
/// ChangeNotifierProvider(create: (_) => Counter2()),
];
上面的注册就写成
runApp(
MultiProvider(
providers: providers,
child: const MyApp(),
),
);
组件的基本写法不变,举个例子:
/// 原来的
RaisedButton(
onPressed:() {/// to do something},
child: Icon(Icons.add),
),
/// 新的
RaisedButton(
onPressed:() {context.read<Counter>().timer()} ,
child: Icon(Icons.add),
),
context.read
表示触发Counter
中的timer
方法
/// 原来的
ListBody(
children: [
Text('一个标题'),
Text('第二个标题'),
],
)
/// 新的
ListBody(
children: [
Text('${context.watch().time[0]}' ),
Text('${context.watch().time[1]}' ),
],
)
通过context.watch
来获取T
中的值(time 是个get方法,返回值为Counter 中的_time,Counter中每过1秒,_time值就更新一次。)
至此,完结。
第二集在此
Flutter provider的简单使用(二)
附一个ChangeNotifier的代码模板,在“Setting -> Editor -> Live Templates” 中添加,生成后将class $name$ with ChangeNotifier, DiagnosticableTreeMixin
中的$name$
修改一下,不要和void $name$()
一致。
import 'package:flutter/foundation.dart';
/// $name$
class $name$ with ChangeNotifier, DiagnosticableTreeMixin{
var _$name$data;
get $name$data => _$name$data;
void $name$(){
}
@override
void debugFillProperties(DiagnosticPropertiesBuilder properties) {
super.debugFillProperties(properties);
properties.add(ObjectFlagProperty('$name$', $name$data));
}
}