本文代码地址:gitee.com/gyy_xiaobai…
一,Flutter的状态管理框架有很多,我们今天使用谷歌官方的 Provider
1, 第一步:在yaml中引入依赖,然后执行flutter pub get
provider: ^6.0.2
2,之后我们便可以使用Provider实现全局数据的共享(前端通常叫状态管理)
二,具体使用
Provider涉及的概念比较多,这里只分析项目中用到的
1,生产者介绍
> I,Provider,无监听效果的Provider
使用Provider对象,包装具体的Bean
void main() {
runApp(Provider<Book>(
create: (ctx) => Book(),
child: const App(),
));
}
class Book{
String bookName = "春秋";
String authName = '孟子';
}
对Book值的赋值:(在HomePage赋值)
Provider.of<Book>(context, listen: false).bookName = "《诗》《书》《礼》《乐》";
对Book值的获取:(在HomePage获取)
Provider.of<Book>(context).bookName
> II,ChangeNotifierProvider,有监听效果的Provider
使用ChangeNotifierProvider对象,包装具体的Bean
void main() {
runApp(ChangeNotifierProvider<Person>(
create: (ctx) => Person(),
child: const App(),
));
}
class Person with ChangeNotifier{
String name = "name";
int age = 0;
addAge() {
age = age + 1;
notifyListeners();
}
}
对Person值的赋值:(在LoginPage赋值) -------赋值的时候,一定要传listen: false
---------
Provider.of<Person>(context, listen: false).addAge();
对Person值的获取:(在HomePage获取) -------获取的时候,listen可传false,可传true
---------
Provider.of<Person>(context).age.toString()
> III,MultiProvider,当有多个bean需要全局管理,就需要用MultiProvider
void main() {
runApp(
MultiProvider(
providers: [
Provider.value(value: Book()),
ChangeNotifierProvider(create: (context)=> Person())
],
child: const App(),
));
}
对Bean的赋值,和取值,同上面 I, II
2,消费者介绍
> I, Provider.of(context)
Provider.of<Book>(context).bookName,
Book为不可监听的Bean,所以上面代码只可以获取值
Provider.of<Person>(context).age.toString()
Provider.of<Person>(context, listen: true).age
Person为可监听的Bean,上面代码可以获取值,而且还可以监听值得变化
> II,Consumer
Consumer<Person>(
builder: (context, model, child) {
debugPrint('Consumer------------build');
return Text(
model.age.toString(),
);
},
child: const Text(
'Consumer - 监听Bean的变化',
))
Consumer可监听Bean的变化,并重新执行Consumer的builder函数,构建Widget
> III,Consumer和Provider.of(context)的选择
1,对于无监听效果的Bean,使用Provider.of(context)
2,对于有监听效果的Bean,使用Consumer,尽量避免使用Provider.of(context),因为Provider.of(context)会导致整个Page的build重新执行
三,简单的封装
void main() {
runApp(Store.init(const App()));
}
///全局的状态管理
class Store {
static BuildContext? _context;
static init(child) {
return MultiProvider(
child: child,
providers: [
//无监听效果的
Provider.value(value: Book()),
//有监听效果的
ChangeNotifierProvider(create: (context)=> Person())
],
);
}
static setContext(BuildContext context) {
Store._context ??= context;
return context;
}
//获取store<T>
static T of<T>({ bool listen = false}) {
return Provider.of<T>(_context!, listen: listen);
}
}
总结3步:
1,将所有的provider抽取到store文件
2,在mian.dart中,调用runApp(Store.init(const App())) 方法
3,在App的build方法中,调用Store.setContext(context);
然后,前面所有的Provider.of, 就可以换成Store.of,而且不用传上下文了
//Provider.of<Book>(context).bookName
//Store.of<Book>().bookName
debugPrint(Store.of<Book>().bookName);