日常开发中有多种场景需要StatefulWidget组件之间进行通信,例如,PageView页面跳转时需要处理子页面逻辑,Widget间传递数据,回调方法等等,组件间通信可以用Event Bus,Redux等库来实现。本文介绍2种Flutter原生实现StatefulWidget间组件通信的方法。
演示动画
组件通信方法1:Global Key通信
创建一个GlobalKey final key = GlobalKey<MyStatefulWidgetOneState>();
,通过 key.currentState
访问State对象的公共属性和方法。
- 声明一个全局的GlobalKey
final key = GlobalKey<MyStatefulWidgetOneState>();
-
StatefulWidgetOne
的构造方法传入这个key
class MyStatefulWidgetOne extends StatefulWidget {
MyStatefulWidgetOne({ Key key }) : super(key: key);
MyStatefulWidgetOneState createState() =>
MyStatefulWidgetOneState();
}
-
MyStatefulWidgetOneState
种定义updateMessage
方法,这个方法可以作为一个回调在外部触发。
void updateMessage(String msg) {
setState((){
_message = msg;
});
}
-
MyStatefulWidgetTwoState
中,通过key可以取到WidgetOneState的public属性,也能通过调用updateMessage
方法来实现对MyStatefulWidgetTwoState
的更改。
@override
Widget build(BuildContext context) {
return Column(
children: <Widget>[
Divider(),
Text('Widget two'),
Container(height: 20.0,),
RaisedButton(
child: Text("Get Current Message"),
onPressed: () {
setState(() {
_objectOne = key.currentState.message;
});
},
),
Text(_objectOne),
RaisedButton(
child: Text("Update Message"),
onPressed: () {
setState(() {
key.currentState.updateMessage("new message");
});
},
),
],
);
}
方法2:通过ValueNotifier通信
ValueNotifier是一个包含单个值的变更通知器,当它的值改变的时候,会通知它的监听。
- 定义ValueNotifierData类,继承ValueNotifier
class ValueNotifierData extends ValueNotifier<String> {
ValueNotifierData(value) : super(value);
}
- 定义
_WidgetOne
,包含一个ValueNotifierData的实例。
class _WidgetOne extends StatefulWidget {
_WidgetOne({this.data});
final ValueNotifierData data;
@override
_WidgetOneState createState() => _WidgetOneState();
}
-
_WidgetOneState
中给ValueNotifierData实例添加监听。
@override
initState() {
super.initState();
widget.data.addListener(_handleValueChanged);
info = 'Initial mesage: ' + widget.data.value;
}
void _handleValueChanged() {
setState(() {
info = 'Message changed to: ' + widget.data.value;
});
}
- 在
ValueNotifierCommunication
组件中实例化_WidgetOne
,可以通过改变ValueNotifierData
实例的value来触发_WidgetOneState
的更新。
@override
Widget build(BuildContext context) {
ValueNotifierData vd = ValueNotifierData('Hello World');
return Scaffold(
appBar: AppBar(title: Text('Value Notifier Communication'),),
body: _WidgetOne(data: vd),
floatingActionButton: FloatingActionButton(child: Icon(Icons.refresh),onPressed: () {
vd.value = 'Yes';
}),
);
}
源码
点击Github源码浏览下载本示例源码
网友评论