Flutter Provider
Provider是官方推荐的全局状态管理工具
安装
dependencies:
provider: ^4.3.2+2
第一步
import 'package:flutter/material.dart';
// 1.创建自己需要共享的数据
class CounterViewModel extends ChangeNotifier{
int _counter = 100;
int get counter => _counter;
set counter(int value) {
_counter = value;
notifyListeners(); // 监听
}
}
import 'dart:math';
import 'package:HM/store/counter_model.dart';
import 'package:flutter/material.dart';
import 'package:provider/provider.dart';
/*
* 1.创建自己需要共享的数据
* 2.在应用程序的顶层创建 ChangeNotifierProvider
* 3.在其他位置使用共享的数据
* * Provider.of 当Provider中的数据发生改变时,Provider.of所在的Widget整个build方法都会重新构建
* * Consumer (推荐) 当Provider中的数据发生改变时,只会执行consumer的builder方法
* * 在floatingActionButton当中的Icon是最不需要被重新渲染的一个Widget,我们可以将他放入child当中 这样每次修改数据的时候都不会重新build到这个widget
* * Selector: 1.selector方法 对原有的数据进行转换
* 2.shouldRebuild 要不要重新构建
* */
void main() {
runApp(
// 2.在应用程序的顶层创建 ChangeNotifierProvider
ChangeNotifierProvider(
create: (ctx) => CounterViewModel(), //create 放共享数据
child: MyApp(),
)
);
}
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
title: "Flutter Demo",
home: providerContent(),
);
}
}
class providerContent extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text("providerTest"),
),
body: ProviderPage(),
// floatingActionButton: Consumer<CounterViewModel>(
// builder: (ctx,counterVM,child){
// return FloatingActionButton(
// child: child,
// onPressed: (){
// counterVM.counter += 1;
// },
// );
// },
// child:Icon(Icons.add);
// )
floatingActionButton: Selector<CounterViewModel,CounterViewModel>(
selector: (ctx,counterVM) => counterVM, // 对原有的数据进行转换
shouldRebuild: (prev,next) => false, // 这里表示需不需要重新构建
builder: (ctx,counterVM,child){
return FloatingActionButton(
child: child,
onPressed: (){
counterVM.counter += 1;
},
);
},
child:Icon(Icons.add)
),
);
}
}
class ProviderPage extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
ShowData01(),
ShowData02(),
],
),
);
}
}
class ShowData01 extends StatelessWidget {
@override
Widget build(BuildContext context) {
// 3.在其他位置使用共享的数据
int counter = Provider.of<CounterViewModel>(context).counter;
return Container(
color: Colors.lime,
child: Text("当前计数$counter",style: TextStyle(fontSize: 30),),
);
}
}
class ShowData02 extends StatelessWidget {
@override
Widget build(BuildContext context) {
// 3.在其他位置使用共享的数据
int counter = Provider.of<CounterViewModel>(context).counter;
return Container(
color: Colors.pinkAccent,
child: Consumer<CounterViewModel>(
builder: (ctx,counterVM,child){
return Text("当前计数${counterVM.counter}",style: TextStyle(fontSize: 30),);
},
),
);
}
}
Provider.of
Consumer
Selector
当我们数据发送改变的时候,我们不希望floatingActionButton
这个按钮重新 builder
当我们需要有多个状态 model
需要共享的时候我们可以使用 MultiProvider
void main() {
runApp(
// 使用多个状态model
MultiProvider(
providers: [
ChangeNotifierProvider(create: (ctx) => CounterViewModel(),),
ChangeNotifierProvider(create: (ctx) => UserViewModel(UserInfo("Penny",20,"url")),)
],
child: MyApp(),
)
);
}
Consumer2
class ShowData03 extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Consumer2<UserViewModel,CounterViewModel>( // Consumer2 可以使用两种state状态数据
builder: (ctx,userVM,counterVM,child){
return Text(
"nickName:${userVM.user.nickname} counter:${counterVM.counter}",
style: TextStyle(fontSize: 20),
);
},
);
}
}
这样就能拿到两种不同model的数据了