flutter开发实战-实现自定义bottomNavigationBar样式awesome_bottom_bar
在开发过程中,需要自定义bottomNavigationBar样式,可以自定义实现,这里使用的是awesome_bottom_bar库
一、awesome_bottom_bar
在pubspec.yaml中引入awesome_bottom_bar
awesome_bottom_bar: ^1.2.2
二、实现自定义bottomNavigationBar
切换界面使用PageView.builder
PageView 是一个非常重要的组件。比如大多数 App 都包含 Tab 换页效果、图片轮动以及抖音上下滑页切换视频功能等等都可以使用PageView来实现
PageView({Key? key,this.scrollDirection = Axis.horizontal, // 滑动方向this.reverse = false,PageController? controller,this.physics,List<Widget> children = const <Widget>[],this.onPageChanged,//每次滑动是否强制切换整个页面,如果为false,则会根据实际的滑动距离显示页面this.pageSnapping = true,//主要是配合辅助功能用的,后面解释this.allowImplicitScrolling = false,//后面解释this.padEnds = true,
})
切换界面使用PageView.builder,当点击不同的tab时候,可以使用PageController进行切换
PageView.builder(itemBuilder: (BuildContext context, int index) {return KeepAliveWrapper(child: subMainPages[index], keepAlive: true);},itemCount: subMainPages.length,controller: _pageController,physics: NeverScrollableScrollPhysics(),onPageChanged: (index) {_selectedIndex = index;_animationControllerList[_selectedIndex!].forward();_animationControllerList[_lastSelectedIndex!].reverse();},),),
使用默认效果的bottomNavigationBar
bottomNavigationBar: BottomBarDefault(items: buildTabItems(context),backgroundColor: Colors.white,color: Colors.black87,colorSelected: Colors.amber,indexSelected: _selectedIndex,duration: Duration(milliseconds: 200),onTap: (int index) => setState(() {_lastSelectedIndex = _selectedIndex;_pageController.jumpToPage(index);}),),
当需要特殊样式的bottomNavigationBar,时候,比如如下点击后会突出的三角形样式
bottomNavigationBar: BottomBarInspiredInside(items: [TabItem(icon: Icons.home_outlined,title: S.of(context).home,),TabItem(icon: Icons.qr_code_scanner_outlined,title: S.of(context).qrScan,),TabItem(icon: Icons.nature_outlined,title: S.of(context).mine,count: Container(padding: EdgeInsets.all(3.0),decoration: BoxDecoration(border: Border.all(color: Colors.white,width: 1.0,style: BorderStyle.solid,),color: Colors.red,borderRadius: BorderRadius.all(Radius.circular(20.0),),// gradient: LinearGradient(// begin: Alignment.topLeft,// end: Alignment.bottomRight,// colors: [// Colors.red.withOpacity(0.5),// Colors.red.withOpacity(0.3),// Colors.red.withOpacity(1.0),// ],// ),),child: Text("99",style: TextStyle(fontSize: 10,color: Colors.white,fontWeight: FontWeight.w500),),),)],backgroundColor: Colors.lightBlue,color: Colors.white,colorSelected: Colors.white,indexSelected: _selectedIndex,duration: Duration(milliseconds: 200),onTap: (int index) => setState(() {_pageController.jumpToPage(index);}),itemStyle: ItemStyle.hexagon,chipStyle:const ChipStyle(isHexagon: true, background: Colors.blueAccent),),
完整实例代码如下
class MainTabNavigator extends StatefulWidget {const MainTabNavigator({Key? key}) : super(key: key);State<MainTabNavigator> createState() => _MainTabNavigatorState();
}class _MainTabNavigatorState extends State<MainTabNavigator>with TickerProviderStateMixin {PageController _pageController = PageController();int _selectedIndex = 0;late DateTime _lastPressed;List<Widget> subMainPages = [];late List<AnimationController> _animationControllerList;late List<Animation<double>> _animationList;int? _lastSelectedIndex = 0;void initState() {// 设置默认的subMainPages = mainPages;super.initState();_animationControllerList = List<AnimationController>.empty(growable: true);_animationList = List<Animation<double>>.empty(growable: true);for (int i = 0; i < subMainPages.length; ++i) {_animationControllerList.add(AnimationController(duration: Duration(milliseconds: 200), vsync: this));_animationList.add(Tween(begin: 0.0, end: 5.0).chain(CurveTween(curve: Curves.ease)).animate(_animationControllerList[i]));}WidgetsBinding.instance.addPostFrameCallback((_) {_animationControllerList[_selectedIndex!].forward();});}void animationDispose() {for (int i = 0; i < subMainPages.length; ++i) {_animationControllerList[i].dispose();}}void dispose() {// TODO: implement disposeanimationDispose();super.dispose();}Widget build(BuildContext context) {return Scaffold(resizeToAvoidBottomInset: false,body: WillPopScope(onWillPop: () async {if (_lastPressed == null ||DateTime.now().difference(_lastPressed) > Duration(seconds: 1)) {//两次点击间隔超过1秒则重新计时_lastPressed = DateTime.now();return false;}return true;},child: PageView.builder(itemBuilder: (BuildContext context, int index) {return KeepAliveWrapper(child: subMainPages[index], keepAlive: true);},itemCount: subMainPages.length,controller: _pageController,physics: NeverScrollableScrollPhysics(),onPageChanged: (index) {_selectedIndex = index;_animationControllerList[_selectedIndex!].forward();_animationControllerList[_lastSelectedIndex!].reverse();},),),// bottomNavigationBar: BottomBarDefault(// items: buildTabItems(context),// backgroundColor: Colors.white,// color: Colors.black87,// colorSelected: Colors.amber,// indexSelected: _selectedIndex,// duration: Duration(milliseconds: 200),// onTap: (int index) => setState(() {// _lastSelectedIndex = _selectedIndex;// _pageController.jumpToPage(index);// }),// ),bottomNavigationBar: BottomBarInspiredInside(items: [TabItem(icon: Icons.home_outlined,title: S.of(context).home,),TabItem(icon: Icons.qr_code_scanner_outlined,title: S.of(context).qrScan,),TabItem(icon: Icons.nature_outlined,title: S.of(context).mine,count: Container(padding: EdgeInsets.all(3.0),decoration: BoxDecoration(border: Border.all(color: Colors.white,width: 1.0,style: BorderStyle.solid,),color: Colors.red,borderRadius: BorderRadius.all(Radius.circular(20.0),),// gradient: LinearGradient(// begin: Alignment.topLeft,// end: Alignment.bottomRight,// colors: [// Colors.red.withOpacity(0.5),// Colors.red.withOpacity(0.3),// Colors.red.withOpacity(1.0),// ],// ),),child: Text("99",style: TextStyle(fontSize: 10,color: Colors.white,fontWeight: FontWeight.w500),),),)],backgroundColor: Colors.lightBlue,color: Colors.white,colorSelected: Colors.white,indexSelected: _selectedIndex,duration: Duration(milliseconds: 200),onTap: (int index) => setState(() {_pageController.jumpToPage(index);}),itemStyle: ItemStyle.hexagon,chipStyle:const ChipStyle(isHexagon: true, background: Colors.blueAccent),),// bottomNavigationBar: FlashyTabBar(// selectedIndex: _selectedIndex,// showElevation: true,// onItemSelected: (index) => setState(() {// _pageController.jumpToPage(index);// }),// items: [// FlashyTabBarItem(// icon: Icon(Icons.home_outlined),// title: Text(S.of(context).home),// ),// FlashyTabBarItem(// icon: Icon(Icons.qr_code_scanner_outlined),// title: Text(S.of(context).qrScan),// ),// FlashyTabBarItem(// icon: Icon(Icons.nature_outlined),// title: Text(S.of(context).mine),// ),// ],// ), // bottomNavigationBar: BottomNavigationBar();}List<TabItem> buildTabItems(BuildContext context) {TabItem homeItem = TabItem(icon: Icons.home_outlined,title: S.of(context).home,count: buildTabItem(context, 0),);TabItem qsItem = TabItem(icon: Icons.qr_code_scanner_outlined,title: S.of(context).qrScan,count: buildTabItem(context, 1),);TabItem discoveryItem = TabItem(icon: Icons.location_searching_outlined,title: S.of(context).discovery,count: buildTabItem(context, 2),);TabItem mineItem = TabItem(icon: Icons.nature_outlined,title: S.of(context).mine,count: buildTabItem(context, 3),);return [homeItem, qsItem, discoveryItem, mineItem];}Widget buildTabItem(BuildContext context, int index) {return AnimatedBuilder(animation: _animationList[index],builder: (BuildContext context, Widget? child) {return Container(margin: EdgeInsets.only(top: _animationList[index].value,),child: child,);},child: buildTabItemCount(context),);}Widget buildTabItemCount(BuildContext context) {return Container(padding: const EdgeInsets.all(3.0),decoration: BoxDecoration(border: Border.all(color: Colors.white,width: 1.0,style: BorderStyle.solid,),color: Colors.red,borderRadius: const BorderRadius.all(Radius.circular(30.0),),// gradient: LinearGradient(// begin: Alignment.topLeft,// end: Alignment.bottomRight,// colors: [// Colors.red.withOpacity(0.5),// Colors.red.withOpacity(0.3),// Colors.red.withOpacity(1.0),// ],// ),),child: const Text("99",style: TextStyle(fontSize: 10, color: Colors.white, fontWeight: FontWeight.w500),),);}
}
三、小结
flutter开发实战-自定义bottomNavigationBar样式。
https://blog.csdn.net/gloryFlow/article/details/132761946
学习记录,每天不停进步。