实现底部导航栏并点击切换页面可简述为有三种方式
- TabBar + TabBarView
- BottomNavigationBar + BottomNavigationBarItem
- 自定义 BottomAppBar
BottomNavigationBar + BottomNavigationBarItem
bottomNavigationBar 是属于 Scaffold 中的一个位于底部的控件。通常和 BottomNavigationBarItem 配合 开发底部导航栏
常用属性
属性 | 值类型 | 说明 |
---|---|---|
items | BottomNavigationBarItem类型的List | 底部导航栏的显示项 |
onTap | ValueChanged < int > | 点击导航栏子项时的回调 |
currentIndex | int | 当前显示项的下标 |
type | BottomNavigationBarType | 底部导航栏的类型,有fixed和shifting两个类型,显示效果不一样 |
fixedColor | Color | 底部导航栏type为fixed时导航栏的颜色,如果为空的话默认使用ThemeData.primaryColor |
iconSize | double | BottomNavigationBarItem icon的大小 |
BottomNavigationBarItem
底部导航栏要显示的Item,由图标和标题组成
属性 | 值类 | 说明 |
---|---|---|
icon | Widget | 要显示的图标控件,一般都是Iocn |
title | Widget | 要显示的标题控件,一般都是Text |
activeIcon | Widget | 选中时要显示的icon,一般也是Icon |
backgroundColor | Color | BottomNavigationBarType为shifting时的背景颜色 |
简单的一个BottomNavigationBar实现
int _selectedIndex = 0; //底部菜单选中值
Scaffold(
// ... 省略一些代码
body: pages[_selectedIndex], //底部导航栏对应内容
bottomNavigationBar: BottomNavigationBar(
items: <BottomNavigationBarItem>[
BottomNavigationBarItem(icon: Icon(Icons.home), title: Text('首页')),
BottomNavigationBarItem(icon: Icon(Icons.add), title: Text('发布')),
BottomNavigationBarItem(icon: Icon(Icons.menu), title: Text('我的'))
],
currentIndex: _selectedIndex,
type: BottomNavigationBarType.fixed,
fixedColor: Colors.blue,
onTap: _onItemTapped,
),
)
// 点击事件
void _onItemTapped(int index) {
setState(() {
_selectedIndex = index;
});
}
通过点击对应的菜单,显示不同内容
//点击底部导航项要显示的页面
final pages = [
ChildItemView("首页"),
ChildItemView("发布"),
ChildItemView("我的")
];
//BottomNavigationBar子页面
class ChildItemView extends StatefulWidget {
String _title;
ChildItemView(this._title);
@override
_ChildItemViewState createState() => _ChildItemViewState();
}
class _ChildItemViewState extends State<ChildItemView> {
@override
Widget build(BuildContext context) {
return Container(
child: Center(child: Text(widget._title)),
);
}
}
实现效果图:
自定义 BottomAppBar
用BottomAppBar的话导航栏每个图标都需要自己实现选中和未选中动态效果,还需要给每个按钮添加点击事件,比较繁琐。但是BottomAppBar比较灵活,可以实现很炫酷的效果
这里简单展示样式效果,配合悬浮按钮实现凹下去的效果
//悬浮按钮
floatingActionButton: FloatingActionButton(
onPressed: () => print("FloatingActionButton"),
child: IconButton(icon: Icon(Icons.add), onPressed: () {}),
),
//悬浮按钮位置
floatingActionButtonLocation: FloatingActionButtonLocation.centerDocked,
//底部按钮
bottomNavigationBar: BottomAppBar(
color: Colors.blue, //底部工具栏的颜色。
shape:
CircularNotchedRectangle(), //设置底栏的形状,一般使用有缺口的圆形矩形和floatingActionButton融合,
child: Padding(
//里边可以放置大部分Widget,可以自由设计底栏
padding: EdgeInsets.fromLTRB(0, 6, 0, 6),
child: Row(
mainAxisSize: MainAxisSize.max,
mainAxisAlignment: MainAxisAlignment.spaceAround,
children: <Widget>[
Column(
mainAxisSize: MainAxisSize.min,
children: <Widget>[
Icon(
Icons.home,
color: Colors.white,
),
Text("首页", style: TextStyle(color: Colors.white))
],
),
Column(
mainAxisSize: MainAxisSize.min,
children: <Widget>[
Icon(
Icons.home,
color: Colors.transparent,
),
Text("发布", style: TextStyle(color: Colors.white))
],
),
GestureDetector(
child: Column(
mainAxisSize: MainAxisSize.min,
children: <Widget>[
Icon(Icons.person, color: Colors.white),
Text("我的", style: TextStyle(color: Colors.white))
],
))
],
),
),
),