flutter_学习记录_02底部 Tab 切换保持页面状态的几种方法

news/2024/11/24 11:28:22/

一、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”的方法:wantKeepAlivebool get wantKeepAlive => true;
}

http://www.ppmy.cn/news/97541.html

相关文章

Rk1126 实现 yolov5 6.2 推理

基于 RK1126 实现 yolov5 6.2 推理. 转换 ONNX python export.py --weights ./weights/yolov5s.pt --img 640 --batch 1 --include onnx --simplify 安装 rk 环境 安装部分参考网上, 有很多. 参考: https://github.com/rockchip-linux/rknpu 转换 RK模型 并验证 yolov562_t…

手摸手教你用AI生成PPT(本文不卖课)

今天再和大家分享一个AI实践&#xff1a; 如何借力AI帮我制作PPT&#xff1f; 上篇和大家安利了目前不用魔法上网&#xff0c;且不用翻墙的最强AI工具&#xff0c;假设我今天要给大家做一个分享&#xff0c;来介绍Claude&#xff0c;如何搞定PPT呢&#xff1f; 当然是直接问Cla…

传统机器学习(七)支持向量机(1)超平面、SVM硬间隔、软间隔模型和损失函数

传统机器学习(七)支持向量机(1) 1 算法概述 1.1 超平面的理解 1.1.1 超平面公式 我们对“平面”概念的理解&#xff0c;一般是定义在三维空间中的&#xff0c;如下&#xff1a; 假设M和M0为平面上的两点&#xff0c;n为该平面的法向量&#xff0c;那么&#xff0c;通过下图…

MySQL存储引擎对比总结

文章目录 一、存储引擎是什么二、存储引擎有哪些三、常用存储引擎介绍1、InnoDB2、MyISAM3、MEMORY4、MRG_MYISAM &#xff08;MERGE&#xff09;5、ARCHIVE6、BLACKHOLE7、FEDERATED8、CSV9、PERFORMANCE_SCHEMA10、NDB 一、存储引擎是什么 存储引擎是数据库的核心&#xff0…

Cpolar内网穿透本地MariaDB数据库

Cpolar内网穿透本地MariaDB数据库 cpolar内网穿透本地MariaDB数据库&#xff0c;实现外公网环境下使用navicat图形化工具远程连接本地内网的MariaDB数据库 配置MariaDB数据库 安装MariaDB数据库 进入MariaDB数据库官网https://mariadb.com/downloads/community/,然后下载相应的…

centos7安装docker 并创建mysql

Docker 分为 CE 和 EE 两大版本。CE 即社区版&#xff08;免费&#xff0c;支持周期 7 个月&#xff09;&#xff0c;EE 即企业版&#xff0c;强调安全&#xff0c;付费使用&#xff0c;支持周期 24 个月。 Docker CE 分为 stable test 和 nightly 三个更新频道。 官方网站上有…

分布式简要说明

1.分布式简要说明 《分布式系统原理与范型》定义&#xff1a; 分布式系统是若干独立计算机的集合&#xff0c;这些计算机对于用户来说就像单个相关系统。 分布式系统 (distributed system) 是建立在网络之上的软件系统。 随着互联网的发展&#xff0c;网站应用的规模不断扩…

Linux-0.11 文件系统char_dev.c详解

Linux-0.11 文件系统char_dev.c详解 模块简介 char_dev.c文件主要负责字符设备的访问方法。 函数详解 rw_ttyx static int rw_ttyx(int rw,unsigned minor,char * buf,int count,off_t * pos)该函数是串口终端的读写函数。 return ((rwREAD)?tty_read(minor,buf,count):…