底栏切换每次都重新请求是一件非常恶心的事,flutter 中提供了AutomaticKeepAliveClientMixin 帮我们完成页面状态保存效果。
1、AutomaticKeepAliveClientMixin
AutomaticKeepAliveClientMixin 这个 Mixin 是 Flutter 为了保持页面设置的。哪个页面需要保持页面状态,就在这个页面进行混入。
不过使用使用这个 Mixin 是有几个先决条件的:
- 使用的页面必须是 StatefulWidget,如果是 StatelessWidget 是没办法办法使用的。
- 其实只有两个前置组件才能保持页面状态:PageView 和 IndexedStack。
- 重写 wantKeepAlive 方法,如果不重写也是实现不了的。
2、修改index_page.dart
明白基本知识之后,就可以修改 index_page.dart,思路就是增加一个 IndexedStack 包裹在 tabBodies 外边。
整体代码如下:
import 'package:flutter/cupertino.dart'; import 'package:flutter/material.dart'; import 'home_page.dart'; import 'category_page.dart'; import 'cart_page.dart'; import 'member_page.dart'; class IndexPage extends StatefulWidget { _IndexPageState createState() => _IndexPageState(); } class _IndexPageState extends State{ PageController _pageController; final List bottomTabs = [ BottomNavigationBarItem( icon:Icon(CupertinoIcons.home), title:Text('首页') ), BottomNavigationBarItem( icon:Icon(CupertinoIcons.search), title:Text('分类') ), BottomNavigationBarItem( icon:Icon(CupertinoIcons.shopping_cart), title:Text('购物车') ), BottomNavigationBarItem( icon:Icon(CupertinoIcons.profile_circled), title:Text('会员中心') ), ]; final List tabBodies = [ HomePage(), CategoryPage(), CartPage(), MemberPage() ]; int currentIndex= 0; var currentPage ; @override void initState() { currentPage=tabBodies[currentIndex]; _pageController=new PageController() ..addListener(() { if (currentPage != _pageController.page.round()) { setState(() { currentPage = _pageController.page.round(); }); } }); super.initState(); } @override Widget build(BuildContext context) { return Scaffold( backgroundColor: Color.fromRGBO(244, 245, 245, 1.0), bottomNavigationBar: BottomNavigationBar( type:BottomNavigationBarType.fixed, currentIndex: currentIndex, items:bottomTabs, onTap: (index){ setState(() { currentIndex=index; currentPage =tabBodies[currentIndex]; }); }, ), body: IndexedStack( index: currentIndex, children: tabBodies ) ); } }
3、加入Mixin保持页面状态
在 home_page.dart 里加入 AutomaticKeepAliveClientMixin 混入,加入后需要重写 wantKeepAlive 方法。
主要代码如下:
class _HomePageState extends Statewith AutomaticKeepAliveClientMixin { @override bool get wantKeepAlive =>true; }
为了检验结果,我们在 HomePageState 里增加一个 initState,在里边 print 一些内容,如果内容输出了,证明我们的页面重新加载了,如果没输出,证明我们的页面保持了状态。
@override void initState() { super.initState(); print('我打印了哈哈哈哈哈'); }