- 官方推荐的全局状态管理工具
https://pub.dev/packages?q=provider
1. 使用流程
- pubspec.yaml导入工具包并Pub get
- 创建provider数据模型类
- 普通数据模型UserModel
- 创建provider模型
注:
创建模型添加变量后生成get和set方法
要在需要监听的方法最后调用notifyListeners()添加监听
import 'package:flutter/foundation.dart'
import 'package:flutter/material.dart';
import 'package:provider/provider.dart';
//注:
// 模型层添加变量
// 生成getter 和 setter方法 (选中类名快捷键cmd+n)
// set方法中添加监听
class TestProviderModel with ChangeNotifier,DiagnosticableTreeMixin{
int _number = 0;
int get number => _number;
set number(int value) {
_number = value;
notifyListeners();
}
void addNumber(){
_number++;
notifyListeners();
}
// @override
// void debugFillProperties(DiagnosticPropertiesBuilder properties) {
// super.debugFillProperties(properties);
// properties.add(IntProperty('number', _number));
// }
}
- 如果想要暴露数据模型到全局也可如下操作
class UserModel{
String name;
String userID;
bool isAuthor;
bool isVIP;
UserModel(this.name, this.userID, this.isAuthor, this.isVIP);
}
import 'package:cayj_cystudio/model/user_model.dart';
import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
class UserProviderModel with ChangeNotifier,DiagnosticableMixin{
UserModel _user;
UserProviderModel(this._user);
UserModel get user => _user;
set user(UserModel value) {
_user = value;
notifyListeners();
}
}
- app顶层导入provider
- 封装一个初始化文件
List<SingleChildWidget> providerList = [
ChangeNotifierProvider(create: (_)=>TestProviderModel()),
ChangeNotifierProvider(create: (_)=>UserProviderModel(UserModel("cy", "1", true, true)))
];
- main函数中引入使用provider
void main() {
runApp(
MultiProvider(
providers: providerList,
child: MyApp(),
),
);
}
- 使用
class _TestProviderState extends State<TestProvider> {
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text("测试provider"),
),
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
ChildOne(),
ChildTwo()
],
),
),
floatingActionButton: FloatingActionButton(
child: Icon(Icons.add),
onPressed: () => context.read<TestProviderModel>().addNumber(),//使用context.read不会调用rebuild
)
);
}
}
class ChildOne extends StatefulWidget {
@override
_ChildOneState createState() => _ChildOneState();
}
class _ChildOneState extends State<ChildOne> {
@override
Widget build(BuildContext context) {
print("1build");
return Container(
child: Text("1number = ${context.watch<TestProviderModel>().number}"),
);
}
}
class ChildTwo extends StatefulWidget {
@override
_ChildTwoState createState() => _ChildTwoState();
}
class _ChildTwoState extends State<ChildTwo> {
@override
Widget build(BuildContext context) {
print("2build");
// int number = Provider.of<TestProviderModel>(context).number;
return Container(
child: Consumer2<TestProviderModel,UserProviderModel>(
builder: (context,testProvider,userProvider,child){
return Text("testProviderNumber:${testProvider.number}\n用户:${userProvider.user.name}");
},
)
// child: Text("当前用户:${context.watch<UserProviderModel>().user.name}"),
);
}
}
- 简单的调用方式
context.watch<TestProviderModel>().number
context.read<TestProviderModel>().addNumber()
如果不希望widget重复rebuild,可以通过
Widget build(BuildContext context) {
final name = context.select((Person p) => p.name);
return Text(name);
}
或者使用Consumer的方式(指挥调用cosumer内部的builder)
return Container(
child: Consumer2<TestProviderModel,UserProviderModel>(
builder: (context,testProvider,userProvider,child){
return Text("testProviderNumber:${testProvider.number}\n用户:${userProvider.user.name}");
},
)
// child: Text("当前用户:${context.watch<UserProviderModel>().user.name}"),
);