前言:
各位同學(xué)大家好,最近看到群里有同學(xué)提出需求 在頂替或者底部多個(gè)tab切換上面的 widget 能在切換后保持切換之前的效果,今天就趁著有時(shí)間就給大家寫了一個(gè)demo小案例僅供大家參考 那么廢話不多說(shuō) 我們正式開始
準(zhǔn)備工作
需要安裝flutter的開發(fā)環(huán)境:大家可以去看看之前的教程:
1 win系統(tǒng)flutter開發(fā)環(huán)境安裝教程: http://www.itdecent.cn/p/152447bc8718
2 mac系統(tǒng)flutter開發(fā)環(huán)境安裝教程:http://www.itdecent.cn/p/bad2c35b41e3
效果圖:
保持頁(yè)面狀態(tài)

不保持頁(yè)面狀態(tài)

具體實(shí)現(xiàn)
首先我們看到保持頁(yè)面狀態(tài)和不保持頁(yè)面狀態(tài)的 效果
1保持頁(yè)面狀態(tài) 無(wú)論我們?cè)趺辞袚Q 頁(yè)面顯示都是我們切換之前的效果并沒(méi)有重新加載
2 不保持頁(yè)面狀態(tài) 當(dāng)我們切換的時(shí)候就重新加載
這里我們想要實(shí)現(xiàn)切換的頁(yè)面的widget 切換保持頁(yè)面狀態(tài)就需要 繼承 AutomaticKeepAliveClientMixin
并重寫 wantKeepAlive 方法返回true 即可
class Home extends StatefulWidget {
Home({Key key}) : super(key: key);
@override
_HomeState createState() {
return _HomeState();
}
}
class _HomeState extends State<Home> 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("點(diǎn)擊一次增加一次數(shù)值"),
Text("$_cunter",style: TextStyle(fontSize: 20,color: Colors.blue))
],
),
),
floatingActionButton: FloatingActionButton(
onPressed: _intCruementCounter,
tooltip: "Incement",
child: Icon(Icons.add),
),
);
}
}
關(guān)鍵核心代碼
class _HomeState extends State<Home> with AutomaticKeepAliveClientMixin{
@override
bool get wantKeepAlive =>true;
}
添加頁(yè)面代碼邏輯
就是寫了一個(gè)listview做下數(shù)據(jù)展示
import 'package:flutter/material.dart';
/***
* 創(chuàng)建人:xuqing
* 創(chuàng)建時(shí)間:2020年10月16日21:20:58
* 類說(shuō)明: 添加頁(yè)面
*
*/
class Add extends StatefulWidget {
Add({Key key}) : super(key: key);
@override
_AddState createState() {
return _AddState();
}
}
class _AddState extends State<Add> 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條數(shù)據(jù)"),
),
)
);
}
}
設(shè)置頁(yè)面核心代碼邏輯(寫了一個(gè)GridView 顯示網(wǎng)格列表然后我們?cè)邳c(diǎn)擊懸浮按鈕的時(shí)候添加數(shù)據(jù) 每次點(diǎn)擊添加5條)
import 'package:flutter/material.dart';
/***
*
* 創(chuàng)建人:xuqing
* 創(chuàng)建時(shí)間:2020年10月16日20:28:35
* ;類說(shuō)明:設(shè)置頁(yè)面
*
*
*/
class Setting extends StatefulWidget {
Setting({Key key}) : super(key: key);
@override
_SettingState createState() {
return _SettingState();
}
}
class _SettingState extends State<Setting>with AutomaticKeepAliveClientMixin {
List<String>datastirng=[];
@override
bool get wantKeepAlive =>true;
void addlist() {
setState(() {
List<String> 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(
//橫軸元素個(gè)數(shù)
crossAxisCount: 3,
//縱軸間距
mainAxisSpacing: 20.0,
//橫軸間距
crossAxisSpacing: 10.0,
//子組件寬高長(zhǎng)度比例
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(List<String>data, int index){
return Container(
width: 150,
height: 100,
color: Colors.blue,
child:Center(
child: Text(data[index]+"條數(shù)據(jù)"),
),
);
}
}
我們簡(jiǎn)單再說(shuō)下tabkeepstate 切換頁(yè)面實(shí)現(xiàn)這個(gè)我們簡(jiǎn)單講下這個(gè)不是本文的核心重點(diǎn)
具體代碼:
import 'package:flutter/material.dart';
import 'pages/home.dart';
import 'pages/add.dart';
import 'pages/setting.dart';
/**
*
* 創(chuàng)建人:xuqing
* 創(chuàng)建時(shí)間:2020年10月17日15:15:13
* 類說(shuō)明: 頁(yè)面狀態(tài)保持的切換tab
*
*
*/
class TabKeepState extends StatefulWidget {
TabKeepState({Key key}) : super(key: key);
@override
_TabKeepStateState createState() {
return _TabKeepStateState();
}
}
class _TabKeepStateState extends State<TabKeepState> 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: ("主頁(yè)"),),
Tab(icon: Icon(Icons.add),text: ("添加")),
Tab(icon: Icon(Icons.settings),text: ("設(shè)置")),
],
),
),
body: TabBarView(
controller: _tabController,
children: [
Home(),
Add(),
Setting(),
],
),
);
}
}
tabkeepstate 頁(yè)面中我們通過(guò)Scaffold 腳手架框架組件 設(shè)置appBar 然后我們?cè)赼ppbar 的下面添加一個(gè)TabBar ,TabBar 添加3個(gè)tab
bottom: TabBar(
controller: _tabController,
tabs: [
Tab(icon: Icon(Icons.home),text: ("主頁(yè)"),),
Tab(icon: Icon(Icons.add),text: ("添加")),
Tab(icon: Icon(Icons.settings),text: ("設(shè)置")),
],
),
我們?cè)赽ody 設(shè)置TabBarView 組件然后在 TabBarView組件里的 children中依次來(lái)添加我們的 Home Add Setting 等widget
body: TabBarView(
controller: _tabController,
children: [
Home(),
Add(),
Setting(),
],
),
我們用到tabbar 和tabbarview 需要設(shè)置tabcontroller 我們需要繼承 SingleTickerProviderStateMixin
然后在initState 方法和dispose 分別創(chuàng)建和銷毀
class _TabKeepStateState extends State<TabKeepState> with SingleTickerProviderStateMixin {
TabController _tabController;
@override
void initState() {
_tabController = TabController(
length: 3,
vsync: this,
);
super.initState();
}
}
到處保持頁(yè)面狀態(tài)的內(nèi)容我們就講完了 我們是通過(guò)配合 tabbar 和tabbarview 來(lái)切換 當(dāng)然你也可以使用bottomNavigationBar 來(lái)實(shí)現(xiàn)底部切換來(lái)測(cè)試 保持頁(yè)面狀態(tài)的效果 ,這個(gè)同學(xué)們可以自己去實(shí)現(xiàn)。
最后總結(jié):
flutter 提供了比較好用的 AutomaticKeepAliveClientMixin 類讓我們繼承 然后重寫 wantKeepAlive 方返回true我們就可以保存頁(yè)面狀態(tài),寫起來(lái)還是比較簡(jiǎn)單。有興趣的同學(xué)還可以結(jié)合其他組件做出你需要的效果 。我這邊就不張開講了 ,有興趣的同學(xué)可以多嘗試,最后希望我的文章能幫助到各位解決問(wèn)題 ,以后我還會(huì)貢獻(xiàn)更多有用的代碼分享給大家。各位同學(xué)如果覺(jué)得文章還不錯(cuò) ,麻煩給關(guān)注和star,小弟在這里謝過(guò)啦
項(xiàng)目地址:
碼云 :https://gitee.com/qiuyu123/flutter_keepstate/tree/master/lib