Flutter 状态管理provider

前端开发者或者reactNative开发者 对于状态管理应该不会陌生,例如前端大名鼎鼎的redux框架 。

在flutter中,对于状态的同步管理是一项很繁琐的申请,比如我们需要将一个值传入后续的N个widget中,需要一层层的传递,并且对于值同步也很麻烦。

在这样的背景下,各种状态管理框架应运而生了,它可以让我们更方便的管理state,同步数据,等操作

在2019年google io大会,用 provider 取代了之前 的provide 框架 ,provider框架很健壮也有灵活,配置简单,本文主要介绍 provider框架的用法 

1. 添加依赖

在pubspec.yaml文件中添加以下依赖 ,然后执行 flutter pub get 进行下载安装
1
provider: ^3.1.0

2.1 简单使用

相比较于之前的写法,这里我们用Provider.value()的方式进行构件一个APP
flutter APP 入口处添加一下代码
1
2
3
4
5
6
7
8
9
10
11
12
13
void main() => runApp(new ZhiHu());
class ZhiHu extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Provider<String>.value(
value: "hello from provider",
child: MaterialApp(
title: "知乎-高仿版",
home: Index(),
),
);
}
}

在这里,我们将一个 值为 ‘hello from provider’ 的字符串设置为共享,并返回一个materialApp

2.2 获取值

1. 使用consumer的方式获取并返回一个widget
1
2
3
4
5
Consumer(
builder: (BuildContext c,String value,Widget child){
return Text("text : $value");
}
),
2. 直接获取 
1
Provider.of<String>(context)

3. 结合ChangeNotifier 接收监听变化

使用场景如下: 我们在首页有一个按钮显示初始值1,点击跳转到第二个页面,然后改变这个值,返回到首页,看到值同步。 

1. 首先定义我们的 Count类金西行数据监听
1
2
3
4
5
6
7
8
9
10
class Count with ChangeNotifier {//1
int _count;
Count(this._count);

void add() {
_count++;
notifyListeners();//2
}
get count => _count;//3
}
2. 注册provider. 将我们的count注册进去
1
2
3
4
5
return MultiProvider(
providers: [
ChangeNotifierProvider(builder: (_) => Count(1)),
],
child: MaterialApp()
3. 设置 FloatActionButton
1
2
3
4
5
6
7
8
9
10
11
12
13
	floatingActionButton: Consumer<Count>(
builder: (BuildContext context, Count snapshot, Widget child) {
return FloatingActionButton(
onPressed: () {
// snapshot.add()
Navigator.pushNamed(context, "/home");
},

child: Text(
// '${Store.value<Count>(context).count}'
'${snapshot.count}'
),
);
到此为止,完成了首页的开发工作。下面进行第二页的开发,我们显示 count中的数字,使用按钮进行 1 的递加 ,当我们点击按钮,回到首页会发现,按钮上的文字已经改变为我们修改后的值
1
2
3
4
5
6
7
8
9
10
11
12
13
14
Builder(
builder: (context) {
return Text(
'second page: ${Store.value<Count>(context).count}'
);
},
),

RaisedButton(
child: Text("button"),
onPressed: () => {
Store.value<Count>(context).add()
},
),

4. provider的简单封装

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
class Store {
static BuildContext context;
static BuildContext widgetCtx;

static init({context, child}) {
return MultiProvider(
providers: [
// Provider<Count>.value(value: Count(1)),
ChangeNotifierProvider(builder: (_) => Count(1)),
],
child: child,
);
}

static T value<T>(context) {
return Provider.of(context);
}

static Consumer connect<T>({builder, child}) {
return Consumer<T>(builder: builder, child: child);
}
}

参考:
pub.dev/packages/provider