https://api.flutter.dev/flutter/material/BottomNavigationBar-class.html

BottomNavigationBar 是底部导航条,可以让我们定义底部Tab 切换,bottomNavigationBar
是Scaffold 组件的参数。

定义

  1. BottomNavigationBar({
  2. Key key,
  3. @required this.items, //List<BottomNavigationBarItem> 底部导航条按钮集合
  4. this.onTap, //选中变化回调函数
  5. this.currentIndex = 0, //默认选中第几个
  6. this.elevation,
  7. this.type, //BottomNavigationBarType.fixed shifting
  8. Color fixedColor, //选中的颜色
  9. this.backgroundColor, //导航条背景色
  10. this.iconSize = 24.0,
  11. Color selectedItemColor, //选中项的颜色
  12. this.unselectedItemColor,
  13. this.selectedIconTheme, //选中icon的样式 IconThemeData(color: Colors.blue, opacity: 0.3, size: 30),
  14. this.unselectedIconTheme,
  15. this.selectedFontSize = 14.0, //选中项文字大小
  16. this.unselectedFontSize = 12.0,
  17. this.selectedLabelStyle, //选中项文字样式
  18. this.unselectedLabelStyle,
  19. this.showSelectedLabels = true, //是否展示 选中项文字
  20. this.showUnselectedLabels, //是否展示 非选中项文字
  21. this.mouseCursor,
  22. })
  23. BottomNavigationBarItem({
  24. @required this.icon, //未选中时图标
  25. @Deprecated(
  26. 'Use "label" instead, as it allows for an improved text-scaling experience. '
  27. 'This feature was deprecated after v1.19.0.'
  28. )
  29. this.title, //已废弃
  30. this.label,
  31. Widget activeIcon, //选中时图标
  32. this.backgroundColor,
  33. })

简单使用

asdf.gif

  1. import 'package:flutter/material.dart';
  2. class HomePage extends StatefulWidget {
  3. HomePage({
  4. key,
  5. this.index = '0',
  6. }) : super(key: key);
  7. final index;
  8. @override
  9. _HomePageState createState() => _HomePageState();
  10. }
  11. class _HomePageState extends State<HomePage> {
  12. int _currentIndex;
  13. List<Widget> pages = [
  14. Text('首页', textScaleFactor: 4),
  15. Text('教室', textScaleFactor: 4),
  16. Text('我的', textScaleFactor: 4),
  17. ];
  18. @override
  19. void initState() {
  20. super.initState();
  21. _currentIndex = int.parse(widget.index);
  22. }
  23. @override
  24. Widget build(BuildContext context) {
  25. return Scaffold(
  26. appBar: AppBar(
  27. title: Text('首页'),
  28. ),
  29. body: pages[_currentIndex],
  30. bottomNavigationBar: BottomNavigationBar(
  31. type: BottomNavigationBarType.fixed, //fixed 固定效果(默认);shifting
  32. currentIndex: _currentIndex,
  33. unselectedItemColor: Colors.black,
  34. selectedItemColor: Theme.of(context).primaryColor,
  35. onTap: (value) {
  36. setState(() {
  37. _currentIndex = value;
  38. });
  39. },
  40. items: [
  41. BottomNavigationBarItem(label: '首页', icon: Icon(Icons.home)),
  42. BottomNavigationBarItem(label: '教室', icon: Icon(Icons.class_)),
  43. BottomNavigationBarItem(label: '我的', icon: Icon(Icons.sanitizer)),
  44. ],
  45. ),
  46. );
  47. }
  48. }

type为 shifting 效果

BottomNavigationBar有2种显示模式,其中一种是fixed效果,上面的展示就是fixed效果,这也是默认值,另一种是shifting效果,设置shifting时需要设置selectedItemColorunselectedItemColor,效果如下:
asdf.gif

示例:结合PageView

asdf.gif

  1. import 'package:app1/routes/route_push.dart';
  2. import 'package:flutter/material.dart';
  3. import 'package:app1/routes/routes.dart';
  4. // import 'package:app1/routes/application.dart';
  5. class HomePage extends StatefulWidget {
  6. HomePage({
  7. key,
  8. this.index = '0',
  9. }) : super(key: key);
  10. final index;
  11. @override
  12. _HomePageState createState() => _HomePageState();
  13. }
  14. class _HomePageState extends State<HomePage> {
  15. PageController _pageController; //页面控制器
  16. int _currentIndex; //页面索引
  17. // 页面数组
  18. List<Widget> pages = [
  19. Text('首页', textScaleFactor: 4),
  20. Text('教室', textScaleFactor: 4),
  21. Text('我的', textScaleFactor: 4),
  22. ];
  23. @override
  24. void initState() {
  25. super.initState();
  26. _currentIndex = int.parse(widget.index);
  27. _pageController = PageController(
  28. initialPage: _currentIndex, //表示当前加载第几页,默认第一页。
  29. keepPage: true,
  30. viewportFraction: 1, //slider 左右缩小倍数
  31. );
  32. }
  33. @override
  34. Widget build(BuildContext context) {
  35. print('home => $_currentIndex');
  36. return Scaffold(
  37. appBar: AppBar(
  38. title: Text('首页'),
  39. ),
  40. body: PageView(
  41. controller: _pageController,
  42. children: pages,
  43. // physics: NeverScrollableScrollPhysics(), // 禁止滚动
  44. onPageChanged: (value) {
  45. print('onPageChanged => $value');
  46. setState(() {
  47. _currentIndex = value;
  48. });
  49. },
  50. ),
  51. bottomNavigationBar: BottomNavigationBar(
  52. currentIndex: _currentIndex,
  53. unselectedItemColor: Colors.black,
  54. selectedItemColor: Theme.of(context).primaryColor,
  55. onTap: (value) {
  56. print('onTap => $value');
  57. //_pageController.jumpToPage(index); //直接跳转
  58. _pageController.animateToPage(
  59. value,
  60. duration: Duration(milliseconds: 200),
  61. curve: Curves.linear,
  62. );
  63. },
  64. items: [
  65. BottomNavigationBarItem(label: '首页', icon: Icon(Icons.home)),
  66. BottomNavigationBarItem(label: '教室', icon: Icon(Icons.class_)),
  67. BottomNavigationBarItem(label: '我的', icon: Icon(Icons.sanitizer)),
  68. ],
  69. ),
  70. );
  71. }
  72. }

示例:结合floatingActionButton

image.png

  1. import 'package:flutter/material.dart';
  2. class HomePage extends StatefulWidget {
  3. HomePage({
  4. key,
  5. this.index = '0',
  6. }) : super(key: key);
  7. final index;
  8. @override
  9. _HomePageState createState() => _HomePageState();
  10. }
  11. class _HomePageState extends State<HomePage> {
  12. int _currentIndex;
  13. List<Widget> pages = [
  14. Text('首页', textScaleFactor: 4),
  15. Text('教室', textScaleFactor: 4),
  16. Text('我的', textScaleFactor: 4),
  17. ];
  18. @override
  19. void initState() {
  20. super.initState();
  21. _currentIndex = int.parse(widget.index);
  22. }
  23. @override
  24. Widget build(BuildContext context) {
  25. return Scaffold(
  26. appBar: AppBar(
  27. title: Text('首页'),
  28. ),
  29. body: pages[_currentIndex],
  30. bottomNavigationBar: BottomNavigationBar(
  31. currentIndex: _currentIndex,
  32. unselectedItemColor: Colors.black,
  33. selectedItemColor: Theme.of(context).primaryColor,
  34. onTap: (value) {
  35. setState(() {
  36. _currentIndex = value;
  37. });
  38. },
  39. items: [
  40. BottomNavigationBarItem(label: '首页', icon: Icon(Icons.home)),
  41. BottomNavigationBarItem(label: '教室', icon: Icon(Icons.class_)),
  42. BottomNavigationBarItem(label: '我的', icon: Icon(Icons.sanitizer)),
  43. ],
  44. ),
  45. floatingActionButtonLocation: FloatingActionButtonLocation.centerDocked,
  46. floatingActionButton: Container(
  47. height: 70,
  48. width: 70,
  49. padding: EdgeInsets.all(8),
  50. margin: EdgeInsets.only(top: 5),
  51. decoration: BoxDecoration(
  52. borderRadius: BorderRadius.circular(35),
  53. color: Colors.white,
  54. ),
  55. child: FloatingActionButton(
  56. child: Icon(Icons.add, size: 36),
  57. onPressed: () {
  58. setState(() {
  59. this._currentIndex = 1;
  60. });
  61. },
  62. backgroundColor: this._currentIndex == 1 ? Colors.red : Colors.blue,
  63. foregroundColor: Colors.white,
  64. ),
  65. ),
  66. );
  67. }
  68. }