当通过底部tabBar将页面在“首页”和“分类”之间进行切换的时候,每一次进入页面的时候该页面的数据都会重新加载。那么如何让页面保持原来的状态,而不是每次都要重新加载刷新数据呢?有两种方式。

第一种方式:采用IndexdStack

IndexdStack和Stack一样,都是层布局控件,可以在一个控件上面放置另一个控件,但唯一不同的是,IndexdStack在同一时刻只能显示子控件中的一个控件,通过index属性来设置显示的控件。

配置底部导航的核心代码如下:

import 'package:flutter/material.dart';
import 'package:flutter_jdshop/pages/tabs/CategoryPage.dart';
import 'package:flutter_jdshop/pages/tabs/HomePage.dart';
import 'package:flutter_jdshop/pages/tabs/ShoppingCartPage.dart';
import 'package:flutter_jdshop/pages/tabs/UserPage.dart'; class Tabs extends StatefulWidget {
Tabs({Key key}) : super(key: key); _TabsState createState() => _TabsState();
} class _TabsState extends State<Tabs> { int _currentIndex = 0;//记录当前选中哪个页面 List<Widget> _pages = [
HomePage(),
CategoryPage(),
ShoppingCartPage(),
UserPage()
]; @override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: Text("JDShop")),
body: this._pages[this._currentIndex],
bottomNavigationBar: BottomNavigationBar(
fixedColor: Colors.red,//底部导航栏按钮选中时的颜色
type: BottomNavigationBarType.fixed,//底部导航栏的适配,当item多的时候都展示出来
currentIndex: this._currentIndex,
onTap: (index){
setState(() {
this._currentIndex = index;
});
},
items: [
BottomNavigationBarItem(icon: Icon(Icons.home), title: Text("首页")),
BottomNavigationBarItem(icon: Icon(Icons.category), title: Text("分类")),
BottomNavigationBarItem(icon: Icon(Icons.shopping_cart), title: Text("购物车")),
BottomNavigationBarItem(icon: Icon(Icons.people), title: Text("我的"))
],
),
);
}
}

此时还是不可以保持页面状态的。

这里我们将body由

body: this._pages[this._currentIndex],

替换成

body: IndexedStack(
index: this._currentIndex,
children: this._pages,
),

这样就能够实现保持页面状态了,效果如下:

我们可以看到,此时,页面的数据只在最开始进来的时候进行加载,然后就保持住这个页面的状态了,并不会每次进来都进行数据的加载刷新了。

使用IndexedStack来保持页面状态的优点就是配置简单,但是它也有很大的缺点:IndexedStack中管理的子页面在一开始就全部一次性加载出来了,不管有没有显示出来,然后通过index属性来确定到底显示哪一个页面。

第二种方式:AutomaticKeepAliveClientMixin

如果所有的页面都需要保持页面状态,那么就使用indexdStack;如果有些页面需要保持页面状态,有些页面需要进来就刷新,那么我们就需要使用AutomaticKeepAliveMixin这个类来单独控制某个页面的状态。

AutomaticKeepAliveClientMixin相比IndexdStack,配置起来要复杂一些。

AutomaticKeepAliveClientMixin结合底部BottomNavigationBar来保持页面状态的时候,其配置步骤如下:

import 'package:flutter/material.dart';
import 'package:flutter_jdshop/pages/tabs/CategoryPage.dart';
import 'package:flutter_jdshop/pages/tabs/HomePage.dart';
import 'package:flutter_jdshop/pages/tabs/ShoppingCartPage.dart';
import 'package:flutter_jdshop/pages/tabs/UserPage.dart'; class Tabs extends StatefulWidget {
Tabs({Key key}) : super(key: key); _TabsState createState() => _TabsState();
} class _TabsState extends State<Tabs> { int _currentIndex = 0;//记录当前选中哪个页面 //第1步,声明PageController
PageController _pageController; @override
void initState() {
super.initState();
//第2步,初始化PageController
this._pageController = PageController(initialPage: this._currentIndex);
} List<Widget> _pages = [
HomePage(),
CategoryPage(),
ShoppingCartPage(),
UserPage()
]; @override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: Text("JDShop")),
//第3步,将body设置成PageView,并配置PageView的controller属性
body: PageView(
controller: this._pageController,
children: this._pages,
),
bottomNavigationBar: BottomNavigationBar(
fixedColor: Colors.red,//底部导航栏按钮选中时的颜色
type: BottomNavigationBarType.fixed,//底部导航栏的适配,当item多的时候都展示出来
currentIndex: this._currentIndex,
onTap: (index){
setState(() {
//第4步,设置点击底部Tab的时候的页面跳转
this._currentIndex = index;
this._pageController.jumpToPage(this._currentIndex);
});
},
items: [
BottomNavigationBarItem(icon: Icon(Icons.home), title: Text("首页")),
BottomNavigationBarItem(icon: Icon(Icons.category), title: Text("分类")),
BottomNavigationBarItem(icon: Icon(Icons.shopping_cart), title: Text("购物车")),
BottomNavigationBarItem(icon: Icon(Icons.people), title: Text("我的"))
],
),
);
}
}

以上前4步都是在tabs.dart中进行配置的,此时所有的页面还是不可保持页面状态的。然后第5步就是在需要保持页面状态的页面里面混入AutomaticKeepAliveClientMixin类,并将wantKeepAlive方法返回为true,如下所示:

//首页页面
class _HomePageState extends State<HomePage> with AutomaticKeepAliveClientMixin{ @override
bool get wantKeepAlive => true; //分类页面
class _CategoryPageState extends State<CategoryPage> with AutomaticKeepAliveClientMixin{ @override
bool get wantKeepAlive => true;

这样,首页页面和分类页面就实现了页面状态的保持,页面数据只在首次进入该页面的时候进行刷新;而其他没有实现页面保持的页面在每次进入该页面的时候,数据都会刷新。

使用AutomaticKeepAliveClientMixin这个类来保持首页和分类页面状态。

原文地址:https://cloud.tencent.com/developer/article/1507094

Flutter tab切换保持页面状态的两种方法的更多相关文章

  1. 09 Flutter底部Tab切换保持页面状态的几种方法

    IndexedStack:保此所有页面的状态: AutomaticKeepAliveClientMixin:保此部分页面的状态: 修改的页面代码: 页面效果: Tabs.dart import 'pa ...

  2. php如何实现页面回退的两种方法

    发布:thatboy   来源:网络  [大 中 小] 你有没有遇到过这样的情况:表单出错而返回页面时,之前填写的信息全不见了.本文为大家介绍二种支持php页面回退的方法,供大家参考. 本文原始链接: ...

  3. flask 实现登录 登出 检查登录状态 的两种方法的总结

    这里我是根据两个项目的实际情况做的总结,方法一(来自项目一)的登录用的是用户名(字符串)和密码,前后端不分离,用form表单传递数据:方法二用的是手机号和密码登录,前后端分离,以json格式传递数据, ...

  4. 微信小程序--跳转页面常用的两种方法

    一.bindtap="onProductsItemTap"绑定点击跳转事件 在.wxml文件中绑定 在.js文件中实现绑定事件函数 二.navigator标签配合URL跳转法 在w ...

  5. JSP页面打印输出,两种方法。out、《%=

    使用out.println()输出: <%@ page contentType="text/html;charset=UTF-8"%> <html> < ...

  6. js刷新页面有哪几种方法

    js刷新页面有哪几种方法 一.总结 一句话总结:location属性的reload方法即可:document.location.reload() 1.页面刷新有哪常见的8种方法? 1,history. ...

  7. div随页面滚动遇顶固定的两种方法(js&jQuery)

    一.遇顶固定的例子 我一直以为是某个div或层随屏幕滚动,遇顶则固定,离开浏览器顶部又还原这样的例子其实不少,其实它的名字叫“层的智能浮动效果”.目前我们在国内的商业网站上就常常看到这样的效果了.例如 ...

  8. Delphi Windows API判断文件共享锁定状态(OpenFile和CreateFile两种方法)

    一.概述 锁是操作系统为实现数据共享而提供的一种安全机制,它使得不同的应用程序,不同的计算机之间可以安全有效地共享和交换数据.要保证安全有效地操作共享数据,必须在相应的操作前判断锁的类型,然后才能确定 ...

  9. 原生Js 两种方法实现页面关键字高亮显示

    原生Js 两种方法实现页面关键字高亮显示 上网看了看别人写的,不是兼容问题就是代码繁琐,自己琢磨了一下用两种方法都可以实现,各有利弊. 方法一 依靠正则表达式修改 1.获取obj的html2.统一替换 ...

  10. JSP错误页面处理的两种方式

    JSP错误页面处理的两种方式: 方法1(真能针对单一页面生效,不推荐): 出错页面实例 <%@ page language="java" contentType=" ...

随机推荐

  1. 【LeetCode字符串#05】基于个人理解的KMP算法图解,以及应用到strStr()函数实现

    KMP算法(用于实现 strStr()) strStr()函数是用来在一个字符串中搜索是否存在另一个字符串的函数,其匹配字符串方式为KMP算法 KMP算法基础理论 假设有如下两个字符串 文本串 aab ...

  2. flutter系列之:使用SliverList和SliverGird

    目录 简介 SliverList和SliverGird详解 SliverList和SliverGird的使用 总结 简介 在上一篇文章我们讲解SliverAppBar的时候有提到过,Sliver的组件 ...

  3. Seal 0.4 发布:软件供应链安全洞察更上一层楼!

    今天,我们很高兴宣布 Seal 0.4 已正式发布!在上一个版本中,Seal 完成了从单一产品到全链路平台的转变,通过全局视图帮助用户掌握软件开发生命周期各个环节的安全状况. 在 Seal 0.4 中 ...

  4. Netty进阶

    1.Netty问题 TCP协议都存在着黏包和半包问题,但是UDP没有 1.粘包现象 发送方分10次发送,接收方一次接受了10次发送的消息 2.半包现象 调整服务器的接受缓冲区大小(调小) 半包会导致服 ...

  5. Spring Boot 小知识、小demo、配置文件

    五.spring boot 通过springboot可以快速的搭建一个基于ssm框架的Java application,简单配置,自动装配. JavaConfiguration用java类来替代xml ...

  6. 【vite】踩坑,首次点击路由跳转页面,发生回退,页面闪回,二次点击才能进入目标页面

    [vite]踩坑,首次点击路由跳转页面,发生回退,页面闪回,二次点击才能进入目标页面 最近在做移动端前端项目,使用的vite3+vue3+vant,组件和api挂载,使用的自动导入,unplugin- ...

  7. JZOJ 3226. 【HBOI2013】ALO

    题目 网上自己搜 解析 区间异或很容易想到可持久化字典树 但本题的关键是如何高效率求出以某个数为区间最大值时这个区间的范围 依题我们知道区间最长可到比它第二大的位置(开区间) 所以我们如果能找到每个数 ...

  8. element导航栏组件封装递归调用

    element导航栏组件封装递归调用: https://blog.csdn.net/qq_21271511/article/details/109889934

  9. 【PyCharm】配置 Git

    一.前提条件 本地先安装好:PyCharm 和 Git 二.操作步骤 1.打开 File -> Settings -> Version Control -> Git,在 Path t ...

  10. Vulnhub:vulnuni1.0.1靶机

    kali:192.168.111.111 靶机:192.168.111.192 信息收集 端口扫描 nmap -A -v -sV -T5 -p- --script=http-enum 192.168. ...