FlutterFlutter学习Flutter

Flutter 保持页面状态案例实现

2020-10-17  本文已影响0人  xq9527

前言:

各位同学大家好,最近看到群里有同学提出需求 在顶替或者底部多个tab切换上面的 widget 能在切换后保持切换之前的效果,今天就趁着有时间就给大家写了一个demo小案例仅供大家参考 那么废话不多说 我们正式开始

准备工作

需要安装flutter的开发环境:大家可以去看看之前的教程:
1 win系统flutter开发环境安装教程: https://www.jianshu.com/p/152447bc8718
2 mac系统flutter开发环境安装教程:https://www.jianshu.com/p/bad2c35b41e3

效果图:

保持页面状态

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

不保持页面状态

不保持状态.gif

具体实现

首先我们看到保持页面状态和不保持页面状态的 效果
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<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("点击一次增加一次数值"),
            Text("$_cunter",style: TextStyle(fontSize: 20,color: Colors.blue))
          ],
        ),
      ),
      floatingActionButton: FloatingActionButton(
        onPressed: _intCruementCounter,
        tooltip: "Incement",
        child: Icon(Icons.add),
      ),
    );
  }
}

关键核心代码

class _HomeState extends State<Home> 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<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条数据"),
        ),
      )
    );
  }
}

设置页面核心代码逻辑(写了一个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 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(
          //横轴元素个数
            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(List<String>data, 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<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: ("主页"),),
            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<TabKeepState> 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

上一篇下一篇

猜你喜欢

热点阅读