Flutter中跨組件數(shù)據(jù)傳遞的方法總結
方法1:InheritedWidget
InheritedWidget:它提供了一種數(shù)據(jù)在Widget樹中從上向下傳遞,共享的方式。我們在應用的根Widget中通過InheritedWidget共享了一個數(shù)據(jù),那么我們可以在任意子Widget中獲取該共享的數(shù)據(jù)!其通用方式就是:
class ShareDataWidget extends InheritedWidget { final int data; ShareDataWidget({this.data, Widget child}) : super(child: child); static ShareDataWidget of(BuildContext context){ return context.dependOnInheritedWidgetOfExactType<ShareDataWidget>(); } @override bool updateShouldNotify(ShareDataWidget oldWidget) { return oldWidget.data !=data; } }
其實就是繼承InheritedWidget
,首先定義需要保存的數(shù)據(jù)比如這里的int型data,然后實現(xiàn)updateShouldNotify
方法,最后定義一個獲取該Widget的靜態(tài)方法,在需要使用該保存數(shù)據(jù)的時候通過這個靜態(tài)方法獲取。使用時,在父widget中傳入需要保存的data,在child中通過定義的靜態(tài)方法來獲取最新值。比如定義的parent如下
class Parent extends StatefulWidget { Parent({Key key}) : super(key: key); _ParentState createState() => _ParentState(); } class _ParentState extends State<Parent> with WidgetsBindingObserver { int _counter = 0; //當Widget第一次插入到Widget樹時會被調(diào)用。對于每一個State對象,F(xiàn)lutter只會調(diào)用該回調(diào)一次 @override void initState() { super.initState(); print("page2 parent initState......"); } @override void setState(fn) { super.setState(fn); print("page2 parent setState......"); } /* *初始化時,在initState之后立刻調(diào)用 *當State的依賴關系發(fā)生變化時,會觸發(fā)此接口被調(diào)用 */ @override void didChangeDependencies() { super.didChangeDependencies(); print("page2 parent didChangeDependencies......"); } @override void didChangeAppLifecycleState(AppLifecycleState state) { print("page2 state is $state"); } //繪制界面 @override Widget build(BuildContext context) { print("page2 parent build......"); return Scaffold( appBar: AppBar(title: Text("setState demo")), body: Center( child: ShareDataWidget( data: _counter, child: RaisedButton( ///點擊事件 onPressed: () { setState(() { _counter++; }); }, child: Child(), ), )), ); } //狀態(tài)改變的時候會調(diào)用該方法,比如父類調(diào)用了setState @override void didUpdateWidget(Parent oldWidget) { super.didUpdateWidget(oldWidget); print("page2 parent didUpdateWidget......"); } //當State對象從樹中被移除時,會調(diào)用此回調(diào) @override void deactivate() { super.deactivate(); print('page2 parent deactivate......'); } //當State對象從樹中被永久移除時調(diào)用;通常在此回調(diào)中釋放資源 @override void dispose() { super.dispose(); print('page2 parent dispose......'); } }
可以看到我們傳入了_counter屬性到ShareDataWidget
中,并且SharedDataWidget
的child需要使用共享的變量。我們的Child定義如下
class Child extends StatefulWidget { Child({Key key}) : super(key: key); @override _ChildState createState() => _ChildState(); } class _ChildState extends State<Child> { //繪制界面 @override Widget build(BuildContext context) { print("child build......"); return Text.rich(TextSpan(children: [ TextSpan( text: '點擊按鈕查看狀態(tài)變化 count: ${ShareDataWidget.of(context).data.toString()}', style: TextStyle(color: Color.fromARGB(100, 255, 0, 0))), TextSpan( text: "新加的一段文本", style: TextStyle(color: Colors.blue), recognizer: TapGestureRecognizer() ..onTap = () { print("點擊了文本"); }) ])); } //當Widget第一次插入到Widget樹時會被調(diào)用。對于每一個State對象,F(xiàn)lutter只會調(diào)用該回調(diào)一次 @override void initState() { super.initState(); print("page2 child initState......"); } /* *初始化時,在initState之后立刻調(diào)用 *當State的依賴關系發(fā)生變化時,會觸發(fā)此接口被調(diào)用 */ @override void didChangeDependencies() { super.didChangeDependencies(); print("page2 child didChangeDependencies......"); } //狀態(tài)改變的時候會調(diào)用該方法,比如父類調(diào)用了setState @override void didUpdateWidget(Child oldWidget) { super.didUpdateWidget(oldWidget); print("page2 child didUpdateWidget......"); } //當State對象從樹中被移除時,會調(diào)用此回調(diào) @override void deactivate() { super.deactivate(); print('page2 child deactivate......'); } //當State對象從樹中被永久移除時調(diào)用;通常在此回調(diào)中釋放資源 @override void dispose() { super.dispose(); print('page2 child dispose......'); } }
其使用就是在Parent中用創(chuàng)建好的ShareDataWidget作為父Widget,在父widget更新需要保存的變量時,同時將數(shù)據(jù)保存在ShareDataWidget的data中,比如上面在parent的build方法中
真正使用這個值的地方是Child類,它的build方法
在parent中觸發(fā)onPress事件其調(diào)用如下
通過使用方式可以看到明顯適用于父->子
方法2:Notification
Notification它的數(shù)據(jù)傳遞方式是從子Widget向上傳遞給父Widget。比如先定義一個notification,這里只有一個msg需要傳遞給父Widget。
class CustomNotification extends Notification{ final String msg; CustomNotification(this.msg); }
然后定義一個子Widget來發(fā)送這個通知
class CustomChild extends StatelessWidget{ @override Widget build(BuildContext context) { return ElevatedButton(onPressed: ()=>CustomNotification("HI").dispatch(context),child: Text("FireNotification"),); } }
在父widget中使用這個通知
class ParentPage extends StatefulWidget { @override State<StatefulWidget> createState() { return _ParentPageState(); } } class _ParentPageState extends State<ParentPage> { String msg = "通知"; @override Widget build(BuildContext context) { return NotificationListener<CustomNotification>( onNotification: (notification){ setState(() { msg+=notification.msg+" "; }); }, child: Column( mainAxisAlignment: MainAxisAlignment.center, children: [Text(msg), CustomChild()], )); } }
可以看到父widget中的根是NotificationListener這個監(jiān)聽器,剛才定義的CustomChild是他的子Widget。
方法3:EventBus
這種方式在Android中也經(jīng)常使用,這個就比較簡單了。首先引用該組件event_bus: ^2.0.0。可以在全局聲明一個EventBus實例,比如在main.dart中。
EventBus bus = new EventBus();
在需要接收訂閱的類中
StreamSubscription subscription; String msg = "event Msg"; //當Widget第一次插入到Widget樹時會被調(diào)用。對于每一個State對象,F(xiàn)lutter只會調(diào)用該回調(diào)一次 @override void initState() { subscription = bus.on<CustomEvent>().listen((event) { setState(() { msg+=event.msg+" "; }); }); super.initState(); print("page1 initState......"); }
這里的subscription
其實就是為了防止泄露的,在dispose
的時候我們要解除訂閱,CustomEvent其實就是一個類,
class CustomEvent{ String msg; CustomEvent(this.msg); }
在需要發(fā)送通知的地方
bus.fire(CustomEvent("我是EventBus發(fā)送的"));
這個比較適合于父->父。也就是所謂的“頁面間”的數(shù)據(jù)傳遞
以上就是Flutter中跨組件數(shù)據(jù)傳遞的方法總結的詳細內(nèi)容,更多關于Flutter數(shù)據(jù)傳遞的資料請關注腳本之家其它相關文章!
相關文章
Android 實現(xiàn)仿網(wǎng)絡直播彈幕功能詳解及實例
這篇文章主要介紹了Android 實現(xiàn)仿網(wǎng)絡直播彈幕功能詳解的相關資料,并附實例代碼及實現(xiàn)效果圖,需要的朋友可以參考下2016-11-11Android 邊播邊緩存的實現(xiàn)(MP4 未加密m3u8)
這篇文章主要介紹了Android 邊播邊緩存的實現(xiàn)(MP4 未加密m3u8),文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧2020-11-11Android開發(fā)中synchronized的三種使用方式詳解
這篇文章主要介紹了Android開發(fā)中synchronized的三種使用方式,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習吧2023-04-04Android中ViewPager的PagerTabStrip與PagerTitleStrip用法實例
這篇文章主要介紹了Android中ViewPager的PagerTabStrip與PagerTitleStrip用法實例,這兩個子控件一般被用作添加標題,在實際效果上并不是那么好控制,使用的時候需要謹慎,需要的朋友可以參考下2016-06-06Android 自定義View實現(xiàn)多節(jié)點進度條功能
這篇文章主要介紹了Android 自定義View實現(xiàn)多節(jié)點進度條,本文通過實例代碼給大家介紹的非常詳細,對大家的學習或工作具有一定的參考借鑒價值,需要的朋友可以參考下2020-05-05react native android6+拍照閃退或重啟的解決方案
android 6+權限使用的時候需要動態(tài)申請,那么在使用rn的時候要怎么處理拍照權限問題呢?本文提供的是一攬子rn操作相冊、拍照的解決方案,需要的朋友可以參考下2017-11-11