一、IndexedStack 保持页面状态
1.1 IndexedStack原理说明
IndexedStack 和 Stack 一样,都是层布局控件, 可以在一个控件上面放置另一 个控件,但唯一不同的是 IndexedStack 在同一时刻只能显示子控件中的一个控 件,通过 Index 属性来设置显示的控件。
IndexedStack 来保持页面状态的优点就是配置简单。IndexedStack 保持页面状 态的缺点就是不方便单独控制每个页面的状态。
1.2 IndexedStack 结合tab用法示例
import 'package:fang_jd/Pages/Category.dart';
import 'package:fang_jd/Pages/Home.dart';
import 'package:fang_jd/Pages/Shop.dart';
import 'package:fang_jd/Pages/User.dart';
import 'package:flutter/material.dart'; class Tabs extends StatefulWidget {const Tabs({super.key});State<Tabs> createState() => _TabsState();
}class _TabsState extends State<Tabs> {late int _currentIndex = 0;final List<Widget> _pageList = const [// 需要替换成自己的页面HomePage(), // 需要替换成自己的页面 CategoryPage(),// 需要替换成自己的页面ShopPage(),// 需要替换成自己的页面UserPage()];Widget build(BuildContext context) {return Scaffold(appBar: AppBar(title: const Text("JD shop"),),// 用IndexedStack实现页面保活body: IndexedStack(// 第一个需要设置的值:要展示哪个页面index: _currentIndex,// 第二个需要设置的值:需要展示的所有页面的数组,需要注意的是,数组必须声明是<Widget>类型children: _pageList,) ,bottomNavigationBar: BottomNavigationBar(currentIndex: _currentIndex,onTap: (index) {setState(() {_currentIndex = index;});} ,type: BottomNavigationBarType.fixed, // 当tab的个数比较多时,必须配置这个值才能显示出来selectedItemColor: Colors.red,items: const [BottomNavigationBarItem(icon: Icon(Icons.home), label: "首页1"),BottomNavigationBarItem(icon: Icon(Icons.category), label: "分类"),BottomNavigationBarItem(icon: Icon(Icons.shop), label: "购物车"),BottomNavigationBarItem(icon: Icon(Icons.people), label: "我的")],));}
}
1.3 IndexedStack的缺点
因为是用数组一次性加载页面的,所以一启动的时候,会把tab下所有的主页面都同时加载出来,增加启动时的负担。例如,刚启动的时候,只需要加载“首页”的数据,但是它会把“分类”、“购物车”、“我的”页面的数据也加载出来。
二、AutomaticKeepAliveClientMixin 保持页面状态
2.1 AutomaticKeepAliveClientMixin原理说明
AutomaticKeepAliveClientMixin 结合 tab 切换保持页面状态相比 IndexedStack 而言配置起来稍 微有些复杂。它结合底部 BottomNavigationBar 保持页面状态的时候需要进行如下配置。
主要步骤如下:
1、添加一个变量:var _pageController;
2、 在tab上的初始化方法,创建页面控制器_pageController = PageController(initialPage : _currentIndex);
3. 在body上,必须使用PageView组件加载不同的页面
//必须用 PageView 加载不同的页面
body: PageView(controller: _pageController, children: this._pageList, onPageChanged: (index){_currentIndex = index;},
4、tab 点击的时候,用页面控制器进行跳转,
_pageController.jumpToPage(this._currentIndex);
onTap: (index){setState(() {//页面控制器进行跳转 _pageController.jumpToPage(this._currentIndex);});
},
5、需要持久化的页面加入如下代码:
5.1 让页面继承“AutomaticKeepAliveClientMixin”
5.2 重写wantKeepAlive的方法,返回值为true
class HomePage extends StatefulWidget {
HomePage({Key key}) : super(key: key);
_HomePageState createState() => _HomePageState();
}class _HomePageState extends State<HomePage> with AutomaticKeepAliveClientMixin{
bool get wantKeepAlive => true;
}
2.2 代码示例
tab的设置
import 'package:fang_jd/Pages/Category.dart';
import 'package:fang_jd/Pages/Home.dart';
import 'package:fang_jd/Pages/Shop.dart';
import 'package:fang_jd/Pages/User.dart';
import 'package:flutter/material.dart'; class Tabs extends StatefulWidget {const Tabs({super.key});State<Tabs> createState() => _TabsState();
}class _TabsState extends State<Tabs> {late int _currentIndex = 0;final List<Widget> _pageList = const [HomePage(),CategoryPage(),ShopPage(),UserPage()];// 添加一个 pageController late PageController _pageController;void initState() {// 在初始化的方法里,初始化_pageController_pageController = PageController(initialPage: _currentIndex);super.initState();}Widget build(BuildContext context) {return Scaffold(appBar: AppBar(title: const Text("JD shop"),),// body 中,必须用pageView来包裹body: PageView(// 第一个需要设置的属性:controller, 用于控制加载页面controller: _pageController,// 第二个需要设置的属性:需要加载哪些页面children: _pageList,) , bottomNavigationBar: BottomNavigationBar(currentIndex: _currentIndex,onTap: (index) {setState(() {_currentIndex = index;_pageController.jumpToPage(_currentIndex);});} ,type: BottomNavigationBarType.fixed, // 当tab的个数比较多时,必须配置这个值才能显示出来selectedItemColor: Colors.red,items: const [BottomNavigationBarItem(icon: Icon(Icons.home), label: "首页1"),BottomNavigationBarItem(icon: Icon(Icons.category), label: "分类"),BottomNavigationBarItem(icon: Icon(Icons.shop), label: "购物车"),BottomNavigationBarItem(icon: Icon(Icons.people), label: "我的")],));}
}
在需要保活的页面的代码设置
class HomePage extends StatefulWidget {const HomePage({super.key});State<HomePage> createState() => _HomePageState();
}// 用with 关键字来继承 “AutomaticKeepAliveClientMixin”
class _HomePageState extends State<HomePage> with AutomaticKeepAliveClientMixin {// 必须重写 “AutomaticKeepAliveClientMixin”的方法:wantKeepAlive bool get wantKeepAlive => true;
}