Flutter底部导航栏BottomNavigationBar页面状态保持解决方案


在实际应用开发中,一般应用的首页面会有这种结构,在Flutter应用开发中,有多种方式来实现这种结构布局,在《flutter底部导航栏》一文中有描述

在这里是通过 BottomNavigationBar + BottomNavigationBarItem,然后页面主体结是通过Scaffold的body配置的动态从页面List中取Widget,也就是说先把三个tab页面存放在了List中,然后根据不同的选择标签来加载不同的页面显示

上述这种写法造成的结果就是每当切换一次页面时,对应的tab页面就会重新初始化加载一次,这样的效果,在实际应用中是体验非常不好的,同时在应用程序中也会造成资源浪费、流量浪费等种种问题。
在这里插入图片描述
直接上代码


///应用入口

main() =>
    runApp(MaterialApp(
      home: FirstPage(),),);

class FirstPage extends StatefulWidget {
  @override
  State<StatefulWidget> createState() {
    return FirstThemState();
  }
}
class FirstThemState extends State<FirstPage> {

  ///选中的标签
  int _tabIndex =0;
  ///图标区
  List<Icon> normalIcon = [
    Icon(Icons.home),
    Icon(Icons.message),
    Icon(Icons.people)
  ];
  
  List<String> normalTitle =[
    "首页",
    "消息",
    "我的"
  ];

  List<Widget> bodyWidgetList=[
    ScffoldHomeItemPage(0),
    ScffoldHomeItemPage1(1),
    ScffoldHomeItemPage2(2),
  ];

  @override
  Widget build(BuildContext context) {
    ///Scaffold 用来搭建页面的主体结构
    return Scaffold(
      ///页面的头部
      appBar: AppBar(title: Text("标题"),),
      ///页面的主内容区
      ///可以是单独的StatefulWidget 也可以是当前页面构建的如Text文本组件
      body:bodyWidgetList[_tabIndex],
      ///底部导航栏
      bottomNavigationBar: buildBottomNavigation(),
    );
  }


  ///构建底部导航栏
  BottomNavigationBar buildBottomNavigation(){

    return new BottomNavigationBar(
      items: <BottomNavigationBarItem>[
        new BottomNavigationBarItem(
            icon: normalIcon[0], title: Text(normalTitle[0])),
        new BottomNavigationBarItem(
            icon:  normalIcon[1], title: Text(normalTitle[1])),
        new BottomNavigationBarItem(
            icon:  normalIcon[2], title: Text(normalTitle[2])),
      ],
      ///显示效果
      type: BottomNavigationBarType.fixed,
      ///当前选中的页面
      currentIndex: _tabIndex,
      ///导航栏的背景颜色
      backgroundColor: Colors.white,
      ///选中时图标与文字的颜色
//      fixedColor: Colors.deepPurple,
      ///选中时图标与文字的颜色
      selectedItemColor: Colors.blue,
      ///未选中时图标与文字的颜色
      unselectedItemColor: Colors.grey,
      ///图标的大小
      iconSize: 24.0,
      ///点击事件
      onTap: (index) {
        setState(() {
          _tabIndex = index;
        });
      },
    );
  }
}

解决方案如下


class FirstThemState extends State<FirstPage> {
   .... .... 
  @override
  Widget build(BuildContext context) {
    ///Scaffold 用来搭建页面的主体结构
    return Scaffold(
      ///页面的头部
      appBar: AppBar(title: Text("标题"),),
      ///页面的主内容区
      body:buildBodyFunction(),
      ///底部导航栏
      bottomNavigationBar: buildBottomNavigation(),
    );
  }

  Widget buildBodyFunction(){
    ///帧布局结合透明布局
   return Stack(children: <Widget>[
     Opacity(opacity: _tabIndex==0?1:0,child: ScffoldHomeItemPage(0),),
     Opacity(opacity: _tabIndex==1?1:0,child: ScffoldHomeItemPage(1),),
     Opacity(opacity: _tabIndex==2?1:0,child: ScffoldHomeItemPage(2),),
   ],);
  }

}


完毕

早起的年轻人 CSDN认证博客专家 移动开发 项目管理 Java
只要用心去做,每一件事情还是有可能成功的,当然成功是没有界限的,只不过是达到自己心里的那个目标,公众号:我的大前端生涯,一个爱喝茶的程序员,通常会搞搞SpringBoot 、Herbinate、Mybatiys、Android、iOS、Flutter、Vue、小程序等.
©️2020 CSDN 皮肤主题: 代码科技 设计师:Amelia_0503 返回首页