Provider

Posted by アライさん on 2020年12月31日

Model

1
2
3
4
5
6
7
8
9
10
import 'package:flutter/foundation.dart';
class TestModel with ChangeNotifier{
String _text = 'default';
String get text => _text;

void setText(){
_text = 'setText';
notifyListeners();
}
}

引入多个Model

1
2
3
4
5
6
7
runApp(MultiProvider(
providers: [
ChangeNotifierProvider(create: (_) => TestModel()),
ChangeNotifierProvider(create: (_) => TestModel1()),
],
child: MyApp(),
));

实际使用的页面

调用,不会监听变化:

1
context.read<PersonState>().updateNickName(nickName)

监听:

1
2
Text(
'${context.watch<PersonState>().productCollectNumber}'),

通过Provider.of:

1
2
//通过listen来设置是否监听变化还是一次性调用
Provider.of<PersonState>(context, listen: false).nickName

防止频繁重构

1
2
3
4
5
//Person其他属性变更也会触发
context.watch<Person>().name;
//只监听name
context.select((Person p)=>p.name);
//使用Consumer或Selector也可以达到指定一部分重构的目的

Consumer

为了抽离不需要rebuild的部分,放入child中

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
Container(
child: Consumer<PersonInfoState>(
//此处参数中的child就是下面"我不会刷新"所在的Container,是不变的部分
builder: (context, personState, child) {
return Column(
children: [
Text(personState.name),
child,
],
);
},
child: Container(
color: Colors.yellow,
height: 200.0,
width: 100,
child: Text('我不会刷新'),
),
),
),

Selector

局部build,只订阅selector返回的值。
可以添加shouldRebuild方法,判断是否rebuild。返回false强制不rebuild。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
Container(
child: Selector<PersonInfoState, String>(
selector: (context, personState) => personState.name,
builder: (context, name, child) {
return Column(
children: [
Text(name),
child,
],
);
},
child: Container(
color: Colors.yellow,
height: 200.0,
width: 100,
child: Text('我不会刷新'),
),
),
),
//搭配Tuple同时监听多个值
Container(
child: Selector<PersonInfoState, Tuple2<String,bool>>(
selector: (context, personState) => Tuple2(personState.name, personState.autoNext),
builder: (context, data, child) {
return Column(
children: [
Text(data.item1),
Text('bool:${data.item2}'),
child,
],
);
},
child: Container(
color: Colors.yellow,
height: 200.0,
width: 100,
child: Text('我不会刷新'),
),
),
),

FutureProvider

支持异步,提供Future,完成后自动刷新子部件。