Flutter 保持頁(yè)面狀態(tài)案例實(shí)現(xiàn)

前言:

各位同學(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)

Screenrecorder-2020-10-17-15-47-36-995[00_00_04--00_00_24].gif

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

不保持狀態(tài).gif

具體實(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

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

友情鏈接更多精彩內(nèi)容