1InheritedWidget提供了数据在树中从上到下传递的共享的方式,可以在任意一个子widget中获取共享数据。
下面介绍一下如何使用InheritedWidget
首先我们需要通过继承InheritedWidget将需要共享的数据data作为MyData的属性。
class MyData extends InheritedWidget{
MyData({this.data,Widget child}):super(child:child);
final int data;//需要在子控件中共享的数据
//提供一个方法让子widget访问的共享数据
static MyData of(BuildContext context ){
return context.dependOnInheritedWidgetOfExactType();
//context.dependOnInheritedWidgetOfExactType获得最近的指定类型的Inherited widget,进而获取它的共享数据。
}
@override
bool updateShouldNotify(MyData oldWidget) {
return oldWidget.data!=data;
// 如果返回true,则子树中依赖(build函数中有调用)本widget的子widget 的state.didChangeDependencies会被调用
}
}
class InheritedDemo extends StatefulWidget {
@override
_InheritedDemoState createState() => _InheritedDemoState();
}
class _InheritedDemoStateextends State {
@override
Widget build(BuildContext context) {
return MyData(
child: Column(
children: [
Test1(),
],
));
}
}
class Test1extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Text(MyData.of(context).data.toString());;
//通过MyData.of就可以获取到共享数据了
}
}
2.Notification是监听机制,在widget树中,每一个节点都可以分发通知,通知会沿着当前节点向上传递,所有父节点都可以通过NotificationListener来监听通知。
1.自定义通知类,继承Notification
class MyNotificationextends Notification {
final Stringmsg;
MyNotification(this.msg);
}
class HomePageextends StatefulWidget {
@override
_HomePageState createState() =>_HomePageState();
}
class _HomePageStateextends State {
String_msg="";
@override
Widget build(BuildContext context) {
//监听通知
return NotificationListener(
onNotification: (notification) {
setState(() {
_msg+=notification.msg+" ";
});
//返回false不会阻止冒泡,父NotificationListener仍然会受到通知,为true时父NotificationListener就不会接受通知
return true;
},
child:Row(
children: [
test(),
Text(_msg)
],
)
);
}
}
class test extends StatelessWidget {
@override
Widget build(BuildContext context) {
return FloatingActionButton(
onPressed: (){
//点击按钮发送通知
MyNotification('haha').dispatch(context);
},
tooltip:'send',
child:Icon(Icons.add),
) ;// ;
}
}
3.Globalkey可以获取到对应的子Widget的State对象
class GlobalKeyDemo extends StatelessWidget {
//创建一个一个ChildPageState类型的GlobalKey
final GlobalKey<_ChildPageState> _globalKey = GlobalKey();
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('GlobalKeyDemo'),
),
//传人创建好的_globalKey
body: ChildPage(key: _globalKey),
floatingActionButton: FloatingActionButton(
child: Icon(Icons.add),
onPressed: () {
//这里的currentState就是_ChildPageState
_globalKey.currentState.data =
'old:' + _globalKey.currentState.count.toString();
_globalKey.currentState.count++;
_globalKey.currentState.setState(() {});
},
),
);
}
}
class ChildPage extends StatefulWidget {
ChildPage({Key key}) :super(key: key);
@override
_ChildPageState createState() => _ChildPageState();
}
class _ChildPageState extends State {
int count =0;
String data ='hello';
@override
Widget build(BuildContext context) {
return Center(
child: Column(
children: [
Text(count.toString()),
Text(data),
],
),
);
}
}
注:通过GlobalKey我们很容易拿到我们想要的子widget的state,从而很容易就实现了局部刷新。