這里學了兩種通信方式铺董,一種是回調、另一種是借用第三方庫event_bus禀晓,其他的還有GlobalKey精续、ValueNotifier、Redux等粹懒,后續(xù)再研究重付。
一、回調
組件間通信可以用回調方式凫乖,這里不需要像java新建一個接口類再實現(xiàn)确垫,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)];
}
}
這段代碼實現(xiàn)了點擊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進行通信了,下面代碼實現(xiàn)了點擊button3可以修改button4的顏色描焰,也就是點擊的時發(fā)送一個事件媳否,button4監(jiān)聽到該事件就改變自身顏色荆秦。
/**
* 以下是用eventbus進行通信
*/
EventBus eventBus = new EventBus();
//新建修改顏色的事件
class ColorEvent{
Color color;
ColorEvent(this.color);
}
//button3
class MyButton3 extends StatelessWidget {
@override
Widget build(BuildContext context) {
return RaisedButton(
//點擊的時候發(fā)送改變顏色事件
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事件,監(jiān)聽到變化的時候調用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