这里学了两种通信方式,一种是回调、另一种是借用第三方库event_bus,其他的还有GlobalKey、ValueNotifier、Redux等,后续再研究。
一、回调
组件间通信可以用回调方式,这里不需要像java新建一个接口类再实现,Dart是支持把方法作为对象传递的,也就是说可以直接把需要回调的方法作为变量传给目标。
/**
* 父子、兄弟组件通信
*/
class WidgetContactDemo extends StatelessWidget {
@override
Widget build(BuildContext context) {
return new Material(
child: new Scaffold(
appBar: new AppBar(
title: new Text("组件间通信"),
),
//主体
body: new ParentWidget(),
));
}
}
//父组件
class ParentWidget extends StatefulWidget {
@override
State createState() {
return _ParentWidget();
}
}
class _ParentWidget extends State<ParentWidget> {
var bgColor; //父组件背景色
var btnColor; //子组件背景色
changeParentColor(color) {
setState(() {
bgColor = color;
});
}
changeButtonColor() {
setState(() {
btnColor = RandomColor().get();
});
}
@override
Widget build(BuildContext context) {
return Container(
width: MediaQuery.of(context).size.width,
color: bgColor,
child: Column(
children: <Widget>[
RaisedButton(
onPressed: changeButtonColor,
child: Text('Button1,点击修改button2背景色'),
),
//这里把方法changeParentColor和变量btnColor传入MyButton,如果changeParentColor是无参函数,可以直接用MyButton(changeParentColor,btnColor),
MyButton((c) => changeParentColor(c), btnColor),
],
),
);
}
}
//子组件按钮,需要传入一个点击事件callback和一个背景色btnColor,点击时会调用callback,而btnColor在外部修改的时候,子组件也会响应修改。
class MyButton extends StatefulWidget {
Function callback;
var btnColor;
//dart构造函数,可以直接把传入参数赋值给相应变量
MyButton(this.callback, this.btnColor);
//下面这种写法的构造函数支持MyButton(callback:(c)=>changeParentColor(c),btnColor:btnColor),
// MyButton({Key key,this.callback,this.btnColor}) : super(key:key) ;
@override
State createState() {
return _MyButton();
}
}
class _MyButton extends State<MyButton> {
@override
Widget build(BuildContext context) {
return RaisedButton(
//State里可以通过widget访问其StatefulWidget里的变量,此处常见错误!不能写作widget.callback(Colors.black12)
onPressed: () => widget.callback(RandomColor().get()),
child: Text('Button2,点击修改父控件背景色'),
color: widget.btnColor,
);
}
}
//随机颜色类
class RandomColor {
final bgColors = [
Colors.white,
Colors.yellow,
Colors.orange,
Colors.cyan,
Colors.lime,
Colors.pinkAccent
];
Color get() {
return bgColors[Random.secure().nextInt(bgColors.length)];
}
}
这段代码实现了点击button1修改button2的颜色,点击button2修改parent的颜色,代码中的new关键字都省略了,这是dart2中的新特性。
从外部修改button2的颜色比较简单,只要在button1点击事件中修改传入button2的变量btnColor即可;
从button2点击修改父组件颜色,就需要用到回调,父控件构建button2的时候传入回调函数MyButton((c) => changeParentColor(c), btnColor),
这里changeParentColor是作为一个对象之间传入子控件赋值给callback的,而子控件在onPressed: () => widget.callback(RandomColor().get()),
这里设置了点击事件,点击时调用widget.callback即changeParentColor,以达到从内部向外部通信的目的,注意不能写成onPressed:widget.callback(RandomColor().get())
二、eventbus
先在pubspec.yaml里增加依赖
dependencies:
flutter:
sdk: flutter
# The following adds the Cupertino Icons font to your application.
# Use with the CupertinoIcons class for iOS style icons.
cupertino_icons: ^0.1.2
event_bus: ^1.0.1//增加依赖
dart文件中再导入包
import 'package:event_bus/event_bus.dart';
接下来就可以使用eventbus进行通信了,下面代码实现了点击button3可以修改button4的颜色,也就是点击的时发送一个事件,button4监听到该事件就改变自身颜色。
/**
* 以下是用eventbus进行通信
*/
EventBus eventBus = new EventBus();
//新建修改颜色的事件
class ColorEvent{
Color color;
ColorEvent(this.color);
}
//button3
class MyButton3 extends StatelessWidget {
@override
Widget build(BuildContext context) {
return RaisedButton(
//点击的时候发送改变颜色事件
onPressed: () => eventBus.fire(ColorEvent(RandomColor().get())),
child: Text('Button3,点击修改Button4颜色'),
);
}
}
//button4
class MyButton4 extends StatefulWidget {
@override
State createState() {
return _MyButton4();
}
}
class _MyButton4 extends State<MyButton4> {
Color bgColor;
@override
void initState() {
//注册eventBus事件,监听到变化的时候调用changeColor(color)
eventBus.on<ColorEvent>().listen((ColorEvent data) => changeColor(data.color));
super.initState();
}
changeColor(color){
//若不对mounted进行判断,会报错 setState() called after dispose()
if(mounted){
setState(() {
bgColor=color;
});
}
}
@override
Widget build(BuildContext context) {
return RaisedButton(
onPressed: ()=>{},//必须给onPressed一个空方法,不能是null,否则无法修改color属性
child: Text('Button4'),
color: bgColor,
);
}
}
eventbus的Git地址:https://github.com/marcojakob/dart-event-bus
详解可参考:https://cloud.tencent.com/developer/article/1338289
网友评论