Flutter数据共享、消息通知与动态对话框

  • 发表于
  • flutter

数据共享(InheritedWidget)从上往下

这里要注意,InheritedWidget的机制是从父控件往子控件共享数据,方向是从上往下传递,继承。文档里讲的那些就不复制了,简单的介绍看这里

消息通知(Notification)从下往上

Notification与InheritedWidget形成相对机制,当你需要把数据和消息从下往上传递、共享的时候,你就用Notification来处理,示例如:

class NotificationRoute extends StatefulWidget {
@override
NotificationRouteState createState() {
return new NotificationRouteState();
}
}

class NotificationRouteState extends State<NotificationRoute> {
String _msg="";
@override
Widget build(BuildContext context) {
//监听通知
return NotificationListener<MyNotification>(
onNotification: (notification) {
setState(() {
_msg+=notification.msg+"";
});
 return true;
},
child: Center(
child: Column(
mainAxisSize: MainAxisSize.min,
children: <Widget>[
Builder(
builder: (context) {
return RaisedButton(
//按钮点击时分发通知
onPressed: () => MyNotification("Hi").dispatch(context),
child: Text("Send Notification"),
);
},
),
Text(_msg)
],
),
),
);
}
}

class MyNotification extends Notification {
MyNotification(this.msg);
final String msg;
}

动态更新对话框数据(StatefulBuilder)

利用StatefulBuilder来实现一些对话框场景,需要对话框动态更新界面的,如果仅是传统的showDialog是无法实现这个需求的。

很多人使用StatefulBuilder依然达不到更新的效果,是因为用错了setState()方法。这个builder构建的控件,不会响应老页面的任何操作,因为它们是两个互不影响的路由控制的。

正确的姿势如下:

showDialog(
context: context,
builder: (context) {
String label = 'test';
return StatefulBuilder(
builder: (context, state) {
print('label = $label');
return GestureDetector(
child: Text(label),
onTap: () {
label = 'test2';
print('onTap: label = $label');
// 注意不是调用老页面的setState,而是要调用builder中的setState
// 在这里为了区分,在构建builder的时候将setState方法命名为了state
state(() {});
},
);
},
);
}
);

在构建builder的时候,返回给了我们两个参数,BuildContext context 和 StateSetter setState,我们要调用的是builder返回给我们的setState,而不是老页面的setState