vlambda博客
学习文章列表

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

  • 网易云【玩转大前端】配套课程

  • EDU配套 教程

  • Flutter开发的点滴积累系列文章

  • 一行代代码置灰应用?对就是这么干


在实际应用开发中,一般应用的首页面会有这种结构,在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),),
],);
}

}

完毕