使用 Flutter 實現(xiàn)帶底部導(dǎo)航欄的 APP 主頁面辛藻,根節(jié)點使用 Scaffold邑彪,再配置 bottomNavigationBar 設(shè)置點擊事件通過調(diào)用 setState()
方法在 build 返回不同的頁面即可翘悉。但運行后會發(fā)現(xiàn)潭苞,點擊切換頁面后之前的頁面狀態(tài)無法保持,切換頁面后再切回之前的頁面惦银,頁面顯示的數(shù)據(jù)會重繪為初始狀態(tài)堕阔。這是因為 flutter 頁面默認(rèn)情況下每次都是返回的一個新的對象棍厂,重新繪制再界面的,不做任何處理的情況下自然不能保留數(shù)據(jù)超陆。要解決這個問題牺弹,有下面的三種實現(xiàn)方式:
一、Stack + OffStage + TickerMode 堆疊
簡單粗暴时呀,跟 Android 開發(fā)中在 FrameLayout 中堆疊 View张漂,再根據(jù)需要控制部分 View 的顯示于隱藏,在構(gòu)建頁面時 body 直接返回一個 Stack 對象谨娜,子 widget 即為要顯示的所有頁面:
@override
Widget build(BuildContext context) {
return new Scaffold(
body: Stack(children: <Widget>[
_makePage(0),
_makePage(1),
_makePage(2),
_makePage(3),
]),
bottomNavigationBar: _getNavigationBar(),
);
/*
* Stack 方式創(chuàng)建頁面
*/
Widget _makePage(int index) {
return Offstage(
offstage: this._currentIndex != index,
child: TickerMode(enabled: this._currentIndex == index, child: _pageList[index]));
}
通過 TickerMode 的 enabled 來控制頁面是否顯示航攒,當(dāng)頁面的 index 為當(dāng)期選中的 index 時顯示否則隱藏。
二趴梢、IndexedStack 控制頁面的顯示
類似 Android 中 FragementTransManager 控制 fragement 的顯示隱藏漠畜,這與第一種方式?jīng)]有太大本質(zhì)上的區(qū)別币他,只不過是顯示判斷邏輯交給 IndexedStack 內(nèi)部自動完成,與第一種方式相比代碼量會少很多
// IndexStack 方式
return new Scaffold(
body: IndexedStack(index: _currentIndex, children: _pageList),
bottomNavigationBar: _getNavigationBar(),
);
三盆驹、PageView
PageView 類似于 Android 中的 ViewPager 支持圆丹,頁面之間的滑動切換滩愁。這種方式需要每一個要保持狀態(tài)的 Widget 狀態(tài)管理類實現(xiàn) AutomaticKeepAliveClientMixin<Widget>
,并且 wangKeepAlive
返回 true躯喇。偽代碼如下:
class WidgetState extends State<Widget>
with AutomaticKeepAliveClientMixin<Widget> {
@override
Widget build(BuildContext context) {
// TODO: implement build
return Widget;
}
@override
// TODO: implement wantKeepAlive
bool get wantKeepAlive => true;
這個樣 PageView 在切換時 flutter 內(nèi)部就會知道你想要保持對應(yīng)頁面的狀態(tài),在頁面切換時會將數(shù)據(jù)保留下來硝枉。這種方式是支持滑動切換頁面的
總結(jié)
不需要支持左右滑動切換頁面直接使用第二種方式實現(xiàn)導(dǎo)航欄效果廉丽,需要滑動切換頁面效果則使用第三種方式。不推薦使用第一種方式實現(xiàn)此功能
Demo