前言:
各位同学大家好,最近看到群里有同学提出需求 在顶替或者底部多个tab切换上面的 widget 能在切换后保持切换之前的效果,今天就趁着有时间就给大家写了一个demo小案例仅供大家参考 那么废话不多说 我们正式开始
准备工作
需要安装flutter的开发环境:大家可以去看看之前的教程:
1 win系统flutter开发环境安装教程: https://www.jianshu.com/p/152447bc8718
2 mac系统flutter开发环境安装教程:https://www.jianshu.com/p/bad2c35b41e3
效果图:
保持页面状态
不保持页面状态
具体实现
首先我们看到保持页面状态和不保持页面状态的 效果
1保持页面状态 无论我们怎么切换 页面显示都是我们切换之前的效果并没有重新加载
2 不保持页面状态 当我们切换的时候就重新加载
这里我们想要实现切换的页面的widget 切换保持页面状态就需要 继承 AutomaticKeepAliveClientMixin
并重写 wantKeepAlive 方法返回true 即可
class Home extends StatefulWidget {
Home({Key key}) : super(key: key);
@override
_HomeState createState() {
return _HomeState();
}
}
class _HomeState extends State with AutomaticKeepAliveClientMixin{
int _cunter=0;
@override
bool get wantKeepAlive =>true;
void _intCruementCounter(){
setState(() {
_cunter++;
});
}
@override
void initState() {
super.initState();
}
@override
void dispose() {
super.dispose();
}
@override
Widget build(BuildContext context) {
// TODO: implement build
return Scaffold(
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Text("点击一次增加一次数值"),
Text("$_cunter",style: TextStyle(fontSize: 20,color: Colors.blue))
],
),
),
floatingActionButton: FloatingActionButton(
onPressed: _intCruementCounter,
tooltip: "Incement",
child: Icon(Icons.add),
),
);
}
}
关键核心代码
class _HomeState extends State with AutomaticKeepAliveClientMixin{
@override
bool get wantKeepAlive =>true;
}
添加页面代码逻辑
就是写了一个listview做下数据展示
import 'package:flutter/material.dart';
/***
* 创建人:xuqing
* 创建时间:2020年10月16日21:20:58
* 类说明: 添加页面
*
*/
class Add extends StatefulWidget {
Add({Key key}) : super(key: key);
@override
_AddState createState() {
return _AddState();
}
}
class _AddState extends State with AutomaticKeepAliveClientMixin {
@override
bool get wantKeepAlive =>true;
@override
void initState() {
super.initState();
}
@override
void dispose() {
super.dispose();
}
@override
Widget build(BuildContext context) {
// TODO: implement build
return Scaffold(
body: ListView.builder(
itemCount: 50,
itemBuilder: (BuildContext context,int index){
return itemWidget(index);
},
),
);
}
Widget itemWidget(int index){
return GestureDetector(
child:Container(
margin: EdgeInsets.fromLTRB(10, 10, 0, 0),
child: Center(
child: Text("我是第$index条数据"),
),
)
);
}
}
设置页面核心代码逻辑(写了一个GridView 显示网格列表然后我们在点击悬浮按钮的时候添加数据 每次点击添加5条)
import 'package:flutter/material.dart';
/***
*
* 创建人:xuqing
* 创建时间:2020年10月16日20:28:35
* ;类说明:设置页面
*
*
*/
class Setting extends StatefulWidget {
Setting({Key key}) : super(key: key);
@override
_SettingState createState() {
return _SettingState();
}
}
class _SettingState extends Statewith AutomaticKeepAliveClientMixin {
Listdatastirng=[];
@override
bool get wantKeepAlive =>true;
void addlist() {
setState(() {
List list = [];
for (int i = 0; i < 5; i++) {
list.add(i.toString());
}
datastirng.addAll(list);
});
}
@override
void initState() {
super.initState();
}
@override
void dispose() {
super.dispose();
}
@override
Widget build(BuildContext context) {
// TODO: implement build
return Scaffold(
body:Container(
child: GridView.builder(
itemCount: datastirng.length,
gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
//横轴元素个数
crossAxisCount: 3,
//纵轴间距
mainAxisSpacing: 20.0,
//横轴间距
crossAxisSpacing: 10.0,
//子组件宽高长度比例
childAspectRatio: 1.0),
itemBuilder: (BuildContext context, int index) {
//Widget Function(BuildContext context, int index)
return getItemContainer(datastirng,index);
}),
),
floatingActionButton: FloatingActionButton(
tooltip: "Incement",
child: Icon(Icons.add),
onPressed: (){
addlist();
},
),
);
}
Widget getItemContainer(Listdata, int index){
return Container(
width: 150,
height: 100,
color: Colors.blue,
child:Center(
child: Text(data[index]+"条数据"),
),
);
}
}
我们简单再说下tabkeepstate 切换页面实现这个我们简单讲下这个不是本文的核心重点
具体代码:
import 'package:flutter/material.dart';
import 'pages/home.dart';
import 'pages/add.dart';
import 'pages/setting.dart';
/**
*
* 创建人:xuqing
* 创建时间:2020年10月17日15:15:13
* 类说明: 页面状态保持的切换tab
*
*
*/
class TabKeepState extends StatefulWidget {
TabKeepState({Key key}) : super(key: key);
@override
_TabKeepStateState createState() {
return _TabKeepStateState();
}
}
class _TabKeepStateState extends State with SingleTickerProviderStateMixin {
TabController _tabController;
@override
void initState() {
_tabController = TabController(
length: 3,
vsync: this,
);
super.initState();
}
@override
void dispose() {
_tabController.dispose();
super.dispose();
}
@override
Widget build(BuildContext context) {
// TODO: implement build
return Scaffold(
appBar: AppBar(
title: Text("keepstatedemo"),
bottom: TabBar(
controller: _tabController,
tabs: [
Tab(icon: Icon(Icons.home),text: ("主页"),),
Tab(icon: Icon(Icons.add),text: ("添加")),
Tab(icon: Icon(Icons.settings),text: ("设置")),
],
),
),
body: TabBarView(
controller: _tabController,
children: [
Home(),
Add(),
Setting(),
],
),
);
}
}
tabkeepstate 页面中我们通过Scaffold 脚手架框架组件 设置appBar 然后我们在appbar 的下面添加一个TabBar ,TabBar 添加3个tab
bottom: TabBar(
controller: _tabController,
tabs: [
Tab(icon: Icon(Icons.home),text: ("主页"),),
Tab(icon: Icon(Icons.add),text: ("添加")),
Tab(icon: Icon(Icons.settings),text: ("设置")),
],
),
我们在body 设置TabBarView 组件然后在 TabBarView组件里的 children中依次来添加我们的 Home Add Setting 等widget
body: TabBarView(
controller: _tabController,
children: [
Home(),
Add(),
Setting(),
],
),
我们用到tabbar 和tabbarview 需要设置tabcontroller 我们需要继承 SingleTickerProviderStateMixin
然后在initState 方法和dispose 分别创建和销毁
class _TabKeepStateState extends State with SingleTickerProviderStateMixin {
TabController _tabController;
@override
void initState() {
_tabController = TabController(
length: 3,
vsync: this,
);
super.initState();
}
}
到处保持页面状态的内容我们就讲完了 我们是通过配合 tabbar 和tabbarview 来切换 当然你也可以使用bottomNavigationBar 来实现底部切换来测试 保持页面状态的效果 ,这个同学们可以自己去实现。
最后总结:
flutter 提供了比较好用的 AutomaticKeepAliveClientMixin 类让我们继承 然后重写 wantKeepAlive 方返回true我们就可以保存页面状态,写起来还是比较简单。有兴趣的同学还可以结合其他组件做出你需要的效果 。我这边就不张开讲了 ,有兴趣的同学可以多尝试,最后希望我的文章能帮助到各位解决问题 ,以后我还会贡献更多有用的代码分享给大家。各位同学如果觉得文章还不错 ,麻烦给关注和star,小弟在这里谢过啦
项目地址:
码云 :https://gitee.com/qiuyu123/flutter_keepstate/tree/master/lib