flutter基礎-元件通訊(父子、兄弟)
上一篇中講了如何通過父元件給子元件傳值:傳送門
這一篇的內容會講述如何實現:
1. 父子元件之間的傳值方法
2. 兄弟元件之間的傳值方法 —— eventbus
實現後的效果如下圖,

實現效果.png
有一些朋友在使用的過程中,可能沒有找到比較好的方法,那麼我們就一起來擼一個demo吧。
這個demo我們重頭開始,先flutter create demo (你的專案名稱), 我們就在官方的demo上面進行修改。
首先我們整體的目錄結構是這樣的

image
然後mian.dart中我們放入parent父元件
class _MyHomePageState extends State<MyHomePage> { @override Widget build(BuildContext context) { return new Scaffold( appBar: new AppBar( title: new Text(widget.title), ), body: new Center( child: new Column( mainAxisAlignment: MainAxisAlignment.center, children: <Widget>[ new Parent() ], ), ), ); } }
父元件中加入childOne, childTwo 兩個子元件
接下來我們來實現父子元件的相互傳值:
void onDataChange(val) { setState(() { data = val; }); } @override Widget build(BuildContext context) { return new Center( child: new Column( mainAxisAlignment: MainAxisAlignment.center, children: <Widget>[ new ChildOne(), new ChildTwo(data4Two: data4Two, callback: (val) => onDataChange(val)), new Container( width: 400.0, margin: const EdgeInsets.all(10.0), padding: const EdgeInsets.only(top:30.0, bottom: 50.0), decoration: BoxDecoration( color: Colors.blue[100]), child: new Column( children: <Widget>[ new Container( padding: new EdgeInsets.only(bottom: 15.0), child:new Text('父元件'), ), new Text('子元件2, 傳過來的值: ' + '$data'), ] ), ) ], ), ); }
通過給childTwo傳入
傳值:data4Two和callback方法
callback方法被呼叫parent中的callback方法,對data進行賦值
接下來我們就只需要在childTwo子元件中觸發callback方法就可以實現傳值了,其實這個和vue的方式很相似u,看程式碼
class ChildTwo extends StatefulWidget { ChildTwo({Key key, this.data4Two, this.callback}) :super(key: key); final callback; String data4Two; @override ChildTwoState createState() => new ChildTwoState(); }
在childTwo元件中,在firedA() 中觸發callback, 就搞定了
void firedA() { widget.callback('$inputTxt'); }
new Container( child: new RaisedButton( onPressed: firedA, child: new Text('to父元件') ) )
接下來我們來實現兄弟元件的傳值。
這裡我們使用eventBus來實現兄弟元件的傳值
eventBus使用流程:
- 引入
import 'package:event_bus/event_bus.dart';
- 建立例項
EventBus eventBus = new EventBus();
- 定義event, 任意一個Dart class都可以作為一個event
class UserLoggedInEvent { User user; UserLoggedInEvent(this.user); }
- 註冊監聽
監聽特定的event
eventBus.on<UserLoggedInEvent>().listen((event) { print(event.user); });
監聽所有的event
eventBus.on().listen((event) { print(event. runtimeType); });
- 傳送一個event
eventBus.fire(new UserLoggedInEvent(myUser));
好的那我們根據上面的步驟,在我們的程式碼中進行實現
1. 首先在pubspec.yaml中加入event_bus, 然後flutter會自動下載的
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 dev_dependencies: flutter_test: sdk: flutter
2. 然後我們在common中新建eventBus.dart檔案
加入以下程式碼:
import 'package:event_bus/event_bus.dart'; EventBus eventBus = new EventBus(); class MyEvent { String text; MyEvent(this.text); }
我們new了一個eventbus物件,然後新建一個叫myEvent的類, 我們就使用myEvent這個類,來實現。
先在childTwo這個元件裡引入eventbus, 並且通過firedB() 方法,呼叫eventBus.fire(), 傳送了一個myEvent()
import '../common/eventBus.dart';
void firedB() { eventBus.fire(new MyEvent('$inputTxt')); }
new Container( child: new RaisedButton( onPressed: firedB, child: new Text('to兄弟元件') ) )
下面的方法是eventBus的監聽事件,
eventBus.on().listen()//監聽eventBus中所有的事件。
eventBus.on<MyEvent>().listen() //只監聽MyEvent。
我們在childOne這個元件裡同樣引入eventBus, 在initState() 初始化方法中,
void initState() { eventBus.on<MyEvent>().listen((MyEvent data) => show(data.text) ); } void show(String val) { setState(() { data= val; }); }
在initState中我們激活了eventBus對MyEvent的監聽,這樣eventBus.fire()方法呼叫一次,我們便可以獲取fire傳送過來的值了。
eventBus是通過Dart Streams來實現的,那麼我們可以通過對Dart Stream的控制,來實現對eventBus的控制
StreamSubscription subscription = eventBus.on<UserLoggedInEvent>().listen((event) { print(event.user); }); subscription.resume();//開 subscription.pause();//暫停 subscription.cancel();//取消
這裡我就不一一實現了,有需要的朋友可以根據業務進行使用。
git地址: ofollow,noindex">https://gitlab.com/carter0624/flutter-eventBus.git