您好,登錄后才能下訂單哦!
這期內(nèi)容當中小編將會給大家?guī)碛嘘P(guān)使用Flutter怎么對數(shù)據(jù)進行傳遞,文章內(nèi)容豐富且以專業(yè)的角度為大家分析和敘述,閱讀完這篇文章希望大家可以有所收獲。
在開發(fā)中,數(shù)據(jù)從一個頁面?zhèn)鬟f到另一個頁面事很常用的,在Android 開發(fā)中,通常是通過把數(shù)據(jù)放到 intent 中傳遞過去。在 Flutter 中,數(shù)據(jù)是如何傳遞的呢?
在Flutter 中一切都是Widget,所以數(shù)據(jù)的傳遞就成了數(shù)據(jù)才Widget 中的傳遞。在之前的學習中,數(shù)據(jù)從一個Widget 傳遞到 子 Widget 是通過構(gòu)造函數(shù),一層一層的往里面?zhèn)鳎?widget 的層級比較少,還沒什么問題,要是層級很多,這樣傳遞就太麻煩了。
還好Flutter 還提供了三種方案:InheritedWidget、Notification 和 EventBus來解決數(shù)據(jù)傳遞問題。
InheritedWidget 是 Flutter 中的一個功能型 Widget,適用于在 Widget 樹中共享數(shù)據(jù)的場景。通過它,我們可以高效地將數(shù)據(jù)在 Widget 樹中進行跨層傳遞。
下面看計數(shù)器的例子:
// 1.InheritedWidget,我們定義了一個繼承自它的新類 CountContainer,里面存放需要共享的數(shù)據(jù) //然后,我們將計數(shù)器狀態(tài) count 屬性放到 CountContainer 中,并提供了一個 of 方法方便其子 Widget 在 Widget 樹中找到它。 //最后,我們重寫了 updateShouldNotify 方法,這個方法會在 Flutter 判斷 InheritedWidget 是否需要重建, class CountContainer extends InheritedWidget { static CountContainer of(BuildContext context) => context.dependOnInheritedWidgetOfExactType<CountContainer>(); final _InheritedWidgetHomeState mode; final Function() function; CountContainer( {Key key, @required this.mode, @required this.function, @required Widget child}) : super(key: key, child: child); @override bool updateShouldNotify(covariant InheritedWidget oldWidget) { return this != oldWidget; } } // 2. 通過構(gòu)建方法,把數(shù)據(jù)放到 InheritedWidget中 class _InheritedWidgetHomeState<InheritedWidgetHome> extends State { int count = 0; void _incrementCounter() => setState(() { count++; }); @override Widget build(BuildContext context) { return CountContainer( mode: this, function: _incrementCounter, child: CountWidget(), ); } } // 3. 在子 widget 通過 CountContainer.of方法,獲取到自定義的 InheritedWidget,并從中取得共享的數(shù)據(jù) class CountWidget extends StatelessWidget { @override Widget build(BuildContext context) { CountContainer state = CountContainer.of(context); return Scaffold( appBar: AppBar( title: Text("InheritedWidget demo"), ), body: Text("current count is ${state.mode.count}"), floatingActionButton: FloatingActionButton( child: Icon(Icons.add), onPressed: state.function, ), ); } }
可以看到,InheritedWidget 的數(shù)據(jù)流動方式是從父 Widget 到子 Widget 逐層傳遞。
首先把通過構(gòu)造函數(shù)需要共享的數(shù)據(jù)放到 InheritedWidget 中,然后提供一個靜態(tài)方法,返回自身;
然后在把自定義的 InheritedWidget做為父容器,傳入需要共享的數(shù)據(jù);
最后在子widget 中,通過靜態(tài)方法獲取到 InheritedWidget 對象,自然就拿到里面的數(shù)據(jù)了。
無論是 InheritedWidget 還是 Notificaiton,它們的使用場景都需要依靠 Widget 樹,在使用起來就有點極限了,但Flutter 提供了一個更好的數(shù)據(jù)傳遞方法--EventBus,傳遞數(shù)據(jù)不再受到限制了。
在原生開發(fā)中,也有使用過 事件總線EventBus,F(xiàn)lutter 中實現(xiàn)跨組件通信的機制也是一樣。它遵循發(fā)布 / 訂閱模式,允許訂閱者訂閱事件,當發(fā)布者觸發(fā)事件時,訂閱者和發(fā)布者之間可以通過事件進行交互。發(fā)布者和訂閱者之間無需有父子關(guān)系,甚至非 Widget 對象也可以發(fā)布 / 訂閱。這些特點與其他平臺的事件總線機制是類似的。
由于 EventBus是第三方庫,所以需要引入:
event_bus: 2.0.0
從第二個頁面,把數(shù)據(jù)回傳到第一個頁面
//建立公共的event bus EventBus eventBus = EventBus(); class CustomEvent { String msg; CustomEvent(this.msg); } class _EventBusPager1State extends State { String message = "原來的數(shù)據(jù)"; StreamSubscription subscription; @override void initState() { subscription = eventBus.on<CustomEvent>().listen((event) { setState(() { message = event.msg; }); }); super.initState(); } @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar( title: Text("EventBusPager1"), ), body: Center( child: Text(message), ), floatingActionButton: FloatingActionButton( child: Icon(Icons.open_in_browser), onPressed: () => Navigator.push( context, MaterialPageRoute(builder: (context) => EventBusPager2())), ), ); } @override void dispose() { subscription.cancel(); super.dispose(); } } class EventBusPager2 extends StatelessWidget { @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar( title: Text("EventBusPager2"), ), body: Center( child: Text("EventBusPager1"), ), floatingActionButton: FloatingActionButton( child: Icon(Icons.send), onPressed: () { eventBus.fire(CustomEvent("data from page 2")); Navigator.pop(context); }, ), ); } }
上述就是小編為大家分享的使用Flutter怎么對數(shù)據(jù)進行傳遞了,如果剛好有類似的疑惑,不妨參照上述分析進行理解。如果想知道更多相關(guān)知識,歡迎關(guān)注億速云行業(yè)資訊頻道。
免責聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點不代表本網(wǎng)站立場,如果涉及侵權(quán)請聯(lián)系站長郵箱:is@yisu.com進行舉報,并提供相關(guān)證據(jù),一經(jīng)查實,將立刻刪除涉嫌侵權(quán)內(nèi)容。