1. Stack + OffStage + TickerMode
能保持状态,不能实现懒加载
- Stack:类似Android里的FrameLayout,按照children的顺序依次绘制。用它可以保存所有子页面的状态。
- OffStage:可以控制控件是否参与布局和绘制
- TickerMode:可以控制控件是否动画
Widget _bodyPage() {
return Stack(
children: <Widget> [
_buildPage(0),
_buildPage(1),
_buildPage(2),
_buildPage(3),
]
);
}
Widget _buildPage(int index) {
return Offstage(
offstage: _selectedIndex != index,
child: TickerMode(
enabled: _selectedIndex == index,
child: pages[index]
),
);
}
2. IndexedStack
能保持状态,不能实现懒加载
- IndexedStack仅展示index所对应的页面,切换页面只需要更新index即可
Widget _indexStackBodyPage() {
return IndexedStack(
index: _selectedIndex,
children: pages,
);
}
3. PageView
懒加载+保持状态
如果UI要求子页面可以滑动,那么PageView + BottomNavigationBar是一种解决办法。 用到 PageView + BottomNavigationBar 或者 TabBarView + TabBar 的时候大家会发现当切换到另一页面的时候, 前一个页面就会被销毁。这并不是我们所期望的。好在系统提供了一个AutomaticKeepAliveClientMixin用于自定义是否保存状态。
- PageView 的children需要继承自 StatefulWidget
- PageView 的children对应的 State 需要继承自 AutomaticKeepAliveClientMixin,并实现wantKeepAlive。
...
PageController _pageController = PageController();
...
void _onItemTapped(int index) {
setState(() {
_selectedIndex = index;
});
// PageView 跳转到指定页面
_pageController.animateToPage(index, duration: Duration(seconds: 1), curve: ElasticInOutCurve());
}
Widget _pageViewBodyPage() {
return PageView(
controller: _pageController,
children: pages,
physics: NeverScrollableScrollPhysics(), //禁止滑动
);
}
class _ShopPageState extends State<MarketingScreen> with AutomaticKeepAliveClientMixin {
@override
bool get wantKeepAlive => true; // 返回true
}
网友评论