/ 生活中常部分app底部导航样式 /
从智能手机的普及我们的生活 , 手机已经为我们生活提供了方便 . 购买手机后系统默认安装了很多款app , 随便点开一款手机app 进入应用首页映入眼帘的就是底部导航 . 可以说手机app为我们生活提供了方便 , 同时app里面的底部导航为我们更好的使用应用 . 市面上的app底部导航切换样式都差不多 (分底部Tab 导航栏 和 舵式导航栏) . 点击底部导航选项可以切换到不同功能模块的 , 让用户在使用的时候更加清楚要导航的功能 .
/ app底部导航构造 /
导航选项纯图标
导航纯文本
导航图文混排
/ Flutter 实现底部导航 /
BottomNavigationBarItem
服务于 BottomNavigationBar . 包括属性icon (选项图标)、title (选项包括文本的widget被弃用)、label (导航栏文本值)、backgroundColor、tooltip (长按时选项顶部d出提示 , 长按选项时选项样式不会发生改变)
在flutter sdk 大于1.19.0的版本上使用该参数 , 抛出如下异常 :
backgroundColor 选项有渐变和移动效果状态下的背景颜色
BottomNavigationBar 参数 BottomNavigationBarType 是 BottomNavigationBarType.shifting 生效. 会覆盖导航栏BottomNavigationBar背景颜色 . 访问B站查看效果
tooltip 长按选项d出提示 访问B站查看效果
BottomNavigationBar
底部导航 可以自定义 选项文本、图标样式 . 长按点击d出提示 . 可以使用flutter自带的icon 切换图标的样式 .
items / BottomNavigationBarItem 集合flutter自带的Icon
class StartPage extends StatefulWidget { StartPage({Key? key, this.title}) : super(key: key); final String? title; @override _StartPageState createState() => _StartPageState(); } class _StartPageState extends State{ GlobalKey _stackGk = GlobalKey (); @override Widget build(BuildContext context) { return Scaffold( bottomNavigationBar: BotNavBar( stackValue: (int currentIndex, List tabInt) { _stackGk.currentState!.changeStack(currentIndex, tabInt); }, ), body: StackWidget( key: _stackGk, )); } }
import 'package:flutter/cupertino.dart'; import 'package:flutter_bottom_navigator/base/presenter/IPresenter.dart'; import 'package:flutter_bottom_navigator/base/view/baseView.dart'; import 'package:flutter_bottom_navigator/base/view/IView.dart'; class StackWidget extends baseView { final int? currentIndex; final List? tabInt; StackWidget({this.currentIndex, this.tabInt, Key? key}) : super(key: key); @override baseViewState , baseView> getState() { return StackWState(); } } class StackWState extends baseViewState { int _currentIndex = 0; List ? _tabInt; final List _children = [ Center( child: Text('Page1'), ), Center( child: Text('Page2'), ), ]; @override void initState() { // TODO: implement initState super.initState(); _tabInt = widget.tabInt == null ? [0] : widget.tabInt; } void changeStack(int currentIndex, List tabInt) { setState(() {}); _currentIndex = currentIndex; _tabInt = tabInt; } //Page的显示和隐藏 _child(int _index) { return Offstage( offstage: !(_currentIndex == _index), child: _tabInt!.contains(_index) ? _children[_index] : Container(), ); } @override buildWidget() { // TODO: implement buildWidget return Stack( children: [ _child(0), _child(1), ], ); } }
import 'package:flutter/material.dart'; class BotNavBar extends StatefulWidget { final ValueChanged? stackValue; BotNavBar({Key? key, this.stackValue}) : super(key: key); @override _BotNavBarState createState() => _BotNavBarState(); } class _BotNavBarState extends State{ List tabInt = [0]; int _currentIndex = 0; late var _tabImages; @override void initState() { // TODO: implement initState super.initState(); _tabImages = [ _singleTabImage('home'), _singleTabImage('type'), _singleTabImage('mine'), ]; } BottomNavigationBarItem _singleBotNavItem(_index) { return BottomNavigationBarItem( icon: _getTabIcon( _index, ), backgroundColor: Colors.red, tooltip: '$_index tooltips', //title: Text('$_index title'), label: '$_index label'); } _singleTabImage(_labelPng) { return [ Icon(Icons.message), Icon(Icons.message), ]; } Widget _getTabIcon(int curIndex) { if (curIndex == _currentIndex) { return _tabImages[curIndex][0]; } return _tabImages[curIndex][1]; } @override Widget build(BuildContext context) { return BottomNavigationBar( type: BottomNavigationBarType.fixed, onTap: _onTabTapped, currentIndex: _currentIndex, backgroundColor: Colors.white, selectedItemColor: Colors.blue, unselectedItemColor: Color(0xffAFB1BD), elevation: 6.0, selectedIconTheme: IconThemeData(color: Colors.green), unselectedIconTheme: IconThemeData(color: Colors.red), selectedLabelStyle: TextStyle(inherit: true), //fixedColor: Colors.blue, showUnselectedLabels: true, showSelectedLabels: true, mouseCursor: SystemMouseCursors.move, enableFeedback: false, items: [ _singleBotNavItem(0), _singleBotNavItem(1), ], ); } _onTabTapped(int index) { setState(() {}); _currentIndex = index; if (!tabInt.contains(index)) { tabInt.add(index); } if (widget.stackValue != null) { widget.stackValue!(_currentIndex, tabInt); } } } typedef ValueChanged = void Function( int currentIndex, List tabInt, );
自定义Icon
创建assets 文件夹来存储要读取的自定义图标
在 pubspec.yaml 文件里面配置图片的依赖
_singleTabImage(_labelPng) { return [ Image.asset( 'assets/${_labelPng}_b_select.png', width: 40.0, height: 40.0, ), Image.asset( 'assets/${_labelPng}_b_normal.png', width: 40.0, height: 40.0, ) ]; }elevation / 导航栏阴影Z坐标
selectedLabelStyle / unselectedLabelStyle
导航栏选中文本的样式 (字体颜色、背景颜色、字体权重、字体阴影 、…...)
导航栏选中文本的样式 (字体颜色、背景颜色、字体权重、字体阴影 、……)
showSelectedLabels / showUnselectedLabels是否显示选中时的文本 / 是否显示未选中时的文本
GlobalKey 实现导航局部刷新
StartPage 包含了 内容区域 (StackWidget) 和底部导航 (BotNavBar) . 当首次进入应用时 , 会渲染内容容区域和底部导航 . 当我们需要切换其它导航时 , 要做到切换导航重新渲染内容区域和底部导航而不执行内容区域和底部导航的父控件StartPage的build函数,需要用到GlobalKey来实现点击导航刷新内容区域而不执行StartPage的build函数 .
class _StartPageState extends State{ GlobalKey _stackGk = GlobalKey (); @override Widget build(BuildContext context) { print('StartPage _build'); return Scaffold( bottomNavigationBar: BotNavBar( stackValue: (int currentIndex, List tabInt) { _stackGk.currentState!.changeStack(currentIndex, tabInt); }, ), body: StackWidget( key: _stackGk, )); } }
flutter_bottom_navigator 案例下载
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)