這期內容當中小編將會給大家帶來有關使用Flutter怎么對數據進行傳遞,文章內容豐富且以專業的角度為大家分析和敘述,閱讀完這篇文章希望大家可以有所收獲。
在開發中,數據從一個頁面傳遞到另一個頁面事很常用的,在Android 開發中,通常是通過把數據放到 intent 中傳遞過去。在 Flutter 中,數據是如何傳遞的呢?
在Flutter 中一切都是Widget,所以數據的傳遞就成了數據才Widget 中的傳遞。在之前的學習中,數據從一個Widget 傳遞到 子 Widget 是通過構造函數,一層一層的往里面傳,要是 widget 的層級比較少,還沒什么問題,要是層級很多,這樣傳遞就太麻煩了。
還好Flutter 還提供了三種方案:InheritedWidget、Notification 和 EventBus來解決數據傳遞問題。
InheritedWidget 是 Flutter 中的一個功能型 Widget,適用于在 Widget 樹中共享數據的場景。通過它,我們可以高效地將數據在 Widget 樹中進行跨層傳遞。
下面看計數器的例子:
// 1.InheritedWidget,我們定義了一個繼承自它的新類 CountContainer,里面存放需要共享的數據
//然后,我們將計數器狀態 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. 通過構建方法,把數據放到 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,并從中取得共享的數據
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 的數據流動方式是從父 Widget 到子 Widget 逐層傳遞。
首先把通過構造函數需要共享的數據放到 InheritedWidget 中,然后提供一個靜態方法,返回自身;
然后在把自定義的 InheritedWidget做為父容器,傳入需要共享的數據;
最后在子widget 中,通過靜態方法獲取到 InheritedWidget 對象,自然就拿到里面的數據了。
無論是 InheritedWidget 還是 Notificaiton,它們的使用場景都需要依靠 Widget 樹,在使用起來就有點極限了,但Flutter 提供了一個更好的數據傳遞方法--EventBus,傳遞數據不再受到限制了。
在原生開發中,也有使用過 事件總線EventBus,Flutter 中實現跨組件通信的機制也是一樣。它遵循發布 / 訂閱模式,允許訂閱者訂閱事件,當發布者觸發事件時,訂閱者和發布者之間可以通過事件進行交互。發布者和訂閱者之間無需有父子關系,甚至非 Widget 對象也可以發布 / 訂閱。這些特點與其他平臺的事件總線機制是類似的。
由于 EventBus是第三方庫,所以需要引入:
event_bus: 2.0.0
從第二個頁面,把數據回傳到第一個頁面
//建立公共的event bus
EventBus eventBus = EventBus();
class CustomEvent {
String msg;
CustomEvent(this.msg);
}
class _EventBusPager1State extends State {
String message = "原來的數據";
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怎么對數據進行傳遞了,如果剛好有類似的疑惑,不妨參照上述分析進行理解。如果想知道更多相關知識,歡迎關注億速云行業資訊頻道。
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。