Flutter tab切换页面 push页面返回保持原页面状态

在Flutter应用中,导航栏或Tab切换页面后默认情况下会丢失原页面状态,即每次进入页面时都会重新初始化状态,显然这样增加了额外的开销,并且带来了不好的用户体验。页面保持状态,不重绘,在app中很重要,比如看着朋友圈/热门微博,看到一半,需要切换到其他tab设置点东西,再切换回来,这个时候肯定不需要页面重绘,然后从头开始看吧,而是希望直接接着前面的状态继续看。

因此flutter 官方为我们提供解决方案 我们只需要在导航内需要保持页面状态的子页State中,继承AutomaticKeepAliveClientMixin并重写wantKeepAlive为true即可。

先看效果


Untitled.gif

第一步 新建 main

void main() => runApp(MyApp());

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: TabBarPage(),
    );
  }
}

我们这里吧 TabBarPage单独抽离出来了

class TabBarPage extends StatefulWidget {
  @override
  _TabBarPageState createState() => _TabBarPageState();
}

class _TabBarPageState extends State  with AutomaticKeepAliveClientMixin{
  @override
  bool get wantKeepAlive => true;
  var _currentIndex = 0;

  List titleList = ['首页','我的'];

  final List  tabVC = [HomePage(),MyPage()];
  PageController _pageController;




  @override
  void initState() {
    // TODO: implement initState
    super.initState();
    this._pageController = PageController(initialPage: this._currentIndex);

  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
        appBar: PreferredSize(
          child: AppBar(
              brightness: Brightness.light,
              title: Text(titleList[this._currentIndex],
                style: TextStyle(
                  color: Colors.black,//设置字体颜色
                  fontSize: 20,//设置字体大小
                ),
              ),
//              backgroundColor: Colors.white,//设置导航背景颜色
              elevation: 0,//隐藏底部阴影分割线
              centerTitle: true,//标题
          ),
          preferredSize: Size(double.infinity,44),
        ),
        backgroundColor: Colors.white,

        bottomNavigationBar: BottomNavigationBar(
          currentIndex: this._currentIndex,
          selectedItemColor: Colors.red,
          unselectedItemColor: Colors.grey,
          type:BottomNavigationBarType.fixed,
          selectedLabelStyle: TextStyle(color: Colors.red),
          unselectedLabelStyle: TextStyle(color: Colors.grey),
          unselectedFontSize:14,
//        selectedIconTheme: IconThemeData(),
          elevation: 1,
          onTap: (index){
              this._pageController.jumpToPage(index);
          },

          iconSize: 30,
          items: [
            BottomNavigationBarItem(
                icon: Icon(Icons.home),
                title: Text('首页')
            ),
            BottomNavigationBarItem(
                icon: Icon(Icons.person_outline),
                title: Text('我的')
            )
          ],
        ),
        body:PageView(
          physics: NeverScrollableScrollPhysics(),//禁止滑动
          controller: this._pageController,
          children: this.tabVC,
          onPageChanged: (index){
            setState(() {
              _currentIndex =index;

            });
          },
        )

    );
  }
}

我们在 Home页面需要实现 继承与 AutomaticKeepAliveClientMixin然后重写 bool get wantKeepAlive => true;

class HomePage extends StatefulWidget {
  @override
  _HomePageState createState() => _HomePageState();
} 

class _HomePageState extends Statewith AutomaticKeepAliveClientMixin {
  @override
  bool get wantKeepAlive => true;

  @override
  Widget build(BuildContext context) {
    super.build(context); //必须实现 不然 在push过后页面会刷新
    return ListView.builder(
        itemCount: 100,
        itemBuilder: (context,index){
          return ListTile(
            title: Text('home$index'),
            onTap: (){
              Navigator.push(context, MaterialPageRoute(builder: (context){
                return  MyTest();
              }));
            },
          );
        }
    );
  }
}

在说一下一定要实现的

  1. with AutomaticKeepAliveClientMixin
  2. bool get wantKeepAlive => true;
  3. super.build(context); 一定要写,不然push 过后,页面还是会重置,我就是因为这句话没写苦恼了很久,差不多一个星期才搞定。。 在主页面一定要实现。

你可能感兴趣的:(Flutter tab切换页面 push页面返回保持原页面状态)