Flutter踩坑日记:Tab导航栏保持子页面状态

最近应邀票圈小伙伴躺坑Flutter,项目初步雏形完结。以原来的工具链版本为基础做了Flutter版本,不过后面还是需要优化下项目接入Redux,以及扩展一些Native方法。

这里记录一下在开发过程中碰到的一些小问题。

首先是搭建Tab的时候,切换tab子页面,上一个页面会被释放,导致切换回来时会重新触发initState等生命周期(网络请求是放在这个里面的)

问了一下前同事:“需要使用 bool get wantKeepAlive => true;”,于是网上搜了一下这个玩意儿,以及其他解决方案。

首先说说使用wantKeepAlive的方案:这是Flutter官方提供并推荐的,源自于AutomaticKeepAliveClientMixin用于自定义保存状态。

先看看实现Tab的代码(有几种实现Tab的方式,后续博客更新):

class _TabPageState extends State<TabPage> with SingleTickerProviderStateMixin {
  //属性
  int _tabindex;
  PageController _pageController;

  @override
  void initState() {
    print("tabController");
    super.initState();
    _pageController = new PageController();
    _tabindex = 0;
  }

  //当整个页面dispose时,记得把控制器也dispose掉,释放内存
  @override
  void dispose() {
    _pageController.dispose();
    super.dispose();
  }

  @override
  Widget build(BuildContext context) {
    print("tabIndex $_tabindex");
    return Scaffold(
      body: new PageView(
        children: [new ListPage(), new AppletPage()],
        controller: _pageController,
        physics: new NeverScrollableScrollPhysics(),
        onPageChanged: onPageChanged,
      ),
      bottomNavigationBar: new BottomNavigationBar(
        onTap: navigationTapped,
        currentIndex: _tabindex,
        items: <BottomNavigationBarItem>[
          new BottomNavigationBarItem(
              icon: new Icon(Icons.brightness_5), title: new Text("工具链")),
          new BottomNavigationBarItem(
              icon: new Icon(Icons.map), title: new Text("小程序"))
        ],
      ),
    );
  }

  void navigationTapped(int page) {
    //Animating Page
    _pageController.jumpToPage(page);
  }

  void onPageChanged(int page) {
    setState(() {
      this._tabindex = page;
    });
  }
}

根据官网的要求:

  1. PageView的children需要继承自 StatefulWidget
  2. PageView的children的State需要继承自 AutomaticKeepAliveClientMixin

具体实现如下:

import 'package:flutter/material.dart';

class AppletPage extends StatefulWidget {
  //构造函数
  AppletPage({Key key}) : super(key: key);

  @override
  _AppletPageState createState() => _AppletPageState();
}

class _AppletPageState extends State<AppletPage>
    with AutomaticKeepAliveClientMixin {
  @override
  bool get wantKeepAlive => true; // 返回true

  @override
  Widget build(BuildContext context) {
    return new MaterialApp(
      home: new Scaffold(
        appBar: new AppBar(
          title: new Text("小程序"),
          backgroundColor: Colors.blue, //设置appbar背景颜色
          centerTitle: true, //设置标题是否局中
        ),
        body: new Center(
          child: new Text('敬请期待'),
        ),
      ),
    );
  }
}
posted @ 2019-04-04 18:24  goingta  阅读(1692)  评论(0编辑  收藏  举报