Flutter开发BottomNavigationBar+PageView实现底部导航栏
文章目录前言项目概述项目结构核心实现主应用文件 (main.dart)页面实现为什么使用AutomaticKeepAliveClientMixin问题背景AutomaticKeepAliveClientMixin的作用实现效果代码验证总结运行效果图前言在Flutter开发中底部导航栏是一个非常常见的UI组件几乎所有的应用都会用到它。实现底部导航栏的方式有很多种比如使用BottomNavigationBar配合IndexedStack或者使用BottomNavigationBar配合PageView。本文将介绍一种使用PageViewAutomaticKeepAliveClientMixin的实现方式这种方式不仅可以实现流畅的页面切换还可以保持页面的状态提升用户体验。项目概述本项目是一个Flutter应用实现了一个带有底部导航栏的基本框架包含四个页面首页、影库、游戏和我的。项目使用了PageView来管理页面切换使用AutomaticKeepAliveClientMixin来保持页面状态。项目结构lib/ ├── main.dart # 主应用文件 ├── home/index.dart # 首页 ├── movie/index.dart # 影库页面 ├── game/index.dart # 游戏页面 └── mine/index.dart # 我的页面核心实现主应用文件 (main.dart)主应用文件实现了底部导航栏和PageView的集成主要代码如下importpackage:bottomnavigationbar/game/index.dart;importpackage:bottomnavigationbar/home/index.dart;importpackage:bottomnavigationbar/mine/index.dart;importpackage:flutter/material.dart;importmovie/index.dart;voidmain(){runApp(constMyApp());}classMyAppextendsStatelessWidget{constMyApp({super.key});overrideWidgetbuild(BuildContextcontext){returnMaterialApp(title:Flutter Demo,theme:ThemeData(colorScheme:.fromSeed(seedColor:Colors.deepPurple)),home:constMyHomePage(title:Flutter 底部导航栏),);}}classMyHomePageextendsStatefulWidget{constMyHomePage({super.key,requiredthis.title});finalStringtitle;overrideStateMyHomePagecreateState()_MyHomePageState();}class_MyHomePageStateextendsStateMyHomePage{latePageController_pageController;int _currentIndex0;overridevoidinitState(){super.initState();_pageControllerPageController(initialPage:_currentIndex);}ListBottomNavigationBarItem_getBottomNavigationBarItem(){return[BottomNavigationBarItem(icon:Icon(Icons.home),label:首页),BottomNavigationBarItem(icon:Icon(Icons.movie),label:影库),BottomNavigationBarItem(icon:Icon(Icons.games),label:游戏),BottomNavigationBarItem(icon:Icon(Icons.person),label:我的),];}overrideWidgetbuild(BuildContextcontext){returnScaffold(appBar:AppBar(backgroundColor:Theme.of(context).colorScheme.inversePrimary,title:Text(widget.title),),body:PageView(controller:_pageController,physics:NeverScrollableScrollPhysics(),// 禁止滑动children:[HomeView(),MovieView(),GameView(),MineView()],),bottomNavigationBar:BottomNavigationBar(currentIndex:_currentIndex,type:BottomNavigationBarType.fixed,// 当底部导航页面超过三个时必须要添加type属性onTap:(index){setState((){_currentIndexindex;});_pageController.jumpToPage(index);},items:_getBottomNavigationBarItem(),),);}}页面实现以首页为例其他页面类似importpackage:flutter/cupertino.dart;importpackage:flutter/material.dart;classHomeViewextendsStatefulWidget{constHomeView({super.key});overrideStateHomeViewcreateState()_HomeViewState();}class_HomeViewStateextendsStateHomeViewwithAutomaticKeepAliveClientMixin{overridevoidinitState(){super.initState();print(initState HomeView----------------------);}overrideWidgetbuild(BuildContextcontext){returnCenter(child:Text(HomeView));}overrideboolgetwantKeepAlivetrue;}为什么使用AutomaticKeepAliveClientMixin这是本文的重点我们来详细分析为什么要使用AutomaticKeepAliveClientMixin问题背景在Flutter中当使用PageView时默认情况下当页面切换到不可见状态时Flutter会销毁该页面的状态。这意味着当用户从页面A切换到页面B再切回页面A时页面A会重新初始化执行initState方法。这种行为在某些情况下是合理的但在大多数情况下我们希望页面能够保持其状态比如页面中有网络请求我们不希望每次切换回来都重新请求数据页面中有用户输入我们希望保留用户的输入内容页面中有动画或其他状态我们希望保持动画的状态或其他状态AutomaticKeepAliveClientMixin的作用AutomaticKeepAliveClientMixin是Flutter提供的一个混入类它可以帮助我们保持页面的状态。使用它需要做两件事在State类中混入AutomaticKeepAliveClientMixin实现wantKeepAlivegetter方法返回true当我们使用AutomaticKeepAliveClientMixin后即使页面切换到不可见状态Flutter也不会销毁该页面的状态而是会将其保存在内存中。当页面再次变得可见时它会使用之前保存的状态而不是重新初始化。实现效果在本项目中我们可以看到当我们首次进入应用时所有页面的initState方法都会被调用因为PageView会预加载相邻的页面但当我们在页面之间切换时initState方法不会再次被调用这说明页面的状态已经被成功保持。代码验证我们可以通过查看控制台输出来验证这一点。当我们首次进入应用时控制台会输出initState HomeView---------------------- MovieView initState---------------------- GameView initState--------------- MineView initState----------------------当我们在页面之间切换时控制台不会再输出这些信息这说明页面的状态已经被成功保持。总结本文介绍了一种使用PageViewAutomaticKeepAliveClientMixin实现底部导航栏的方法这种方法不仅可以实现流畅的页面切换还可以保持页面的状态提升用户体验。AutomaticKeepAliveClientMixin是一个非常实用的工具它可以帮助我们解决页面状态管理的问题特别是在使用PageView、TabView等组件时。通过使用它我们可以避免不必要的页面重新初始化提升应用的性能和用户体验。运行效果图