InheritedWidget(不咋使用)
- 原理
1.定义一个共享数据的类HYShareData且继承自InheritedWidget,该类中做了四件事:
定义共享的数据;
定义构造方法,初始化数据及child(下面需要数据的组件要被该类包裹用到child属性);
获取组件最近的当前InheritedWidget,通过定义类方法HYShareData.of();
重写父类的抽象方法updateShouldNotify(HYShareData oldWidget),返回false,不执行依赖当前的InheritedWidget的State中的didChangeDependencies。
2.在需要数据的组件上包裹该类,并且绑定数据属性。
3.在需要数据的地方通过类方法HYShareData.of(context).数据获得。
- 实现部分代码
1.定义共享数据的类
class HYShareData extends InheritedWidget {
final int count;
HYShareData({this.count,Widget child}):super(child:child);
static HYShareData of(BuildContext context){
return context.dependOnInheritedWidgetOfExactType();
}
@override
bool updateShouldNotify(HYShareData oldWidget) {
return oldWidget.count != count;
}
}
2.类包裹组件
body: HYShareData(
count: _count,
child: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
HYData01(),
],
),
),
),
3.获得数据
当前计数:${HYShareData.of(context).count}
Provider(官方推荐)
provider.of()+consumer()
- 特点
优点:代码简单整洁;
缺点:当我们点击了floatingActionButton时,HYHomePage的build方法会被重新调用,这意味着整个HYHomePage的Widget都需要重新build,浪费性能。
- 实现原理
1.创建自己的ChangeNotifier继承自ChangeNotifier来保存数据
2.把ChangeNotifierProvider插入到widget树即应用程序的顶层;
3.在操作数据的地方引入Consumer被其包裹修改数据状态;
4.在需要数据的地方使用Provider.of<自定义类>(context).数据名来获取
- 部分代码实现
1.创建自己的ChangeNotifier:
class HYShareData extends ChangeNotifier {
int _count = 10;
int get count => _count;
set count(int value) {
_count = value;
notifyListeners();
}
}
2.把ChangeNotifierProvider插入顶层树
main(){
runApp(
ChangeNotifierProvider(
create: (context) => HYShareData(),
child: MyApp(),
)
);
}
3.包裹consumer
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
HYData1(),
],
),
),
4.获取数据
int count = Provider.of<HYShareData>(context).count;
return Container(
child: Text('当前计数:$count',style: TextStyle(fontSize: 20)),
);
consumer()+consumer()
- 特点
优点:Consumer在刷新整个Widget树时,会尽可能少的rebuild Widget;
缺点:代码比provider.of()多,会刷新操作数据的build方法。
- 实现
其他步骤与provider.of()+consumer一致,只是在需要使用数据的地方不再通过provider获取,而是通过包裹consumer获取:
return Consumer<HYShareData>(
builder: (context,value,child){
return Text('当前计数:${value.count}',style: TextStyle(fontSize: 20));
},
);
selector()+consumer()
- 特点
不会刷新操作数据(在这里指的是改变数据的按钮floatingActionButton)的build方法。
- 实现
在操作数据的地方即floatingActionButton传入Selector():
floatingActionButton: Selector<HYShareData1,HYShareData2>(
selector: (context,provider) => provider,
shouldRebuild: (pre,next) => false,
builder: (context,ShareData2,child){
return FloatingActionButton(
child: child,
onPressed: (){
ShareData2.count++;
},
);
},
child: Icon(Icons.add),
)
多个provider管理多个数据
runApp(MultiProvider(
providers: [
ChangeNotifierProvider(create: (ctx) => CounterProvider()),
ChangeNotifierProvider(create: (ctx) => UserProvider()),
],
child: MyApp(),
));