实现效果

展示页面内容
- 定义页面组件(首页、分类、购物车、我的)
- 定义页面列表,存放首页、分类、购物车、我的这四个页面组件
- 读取页面组件,并赋值给Scaffold组件的body属性(默认读取并展示首页)

展示底部导航
- 将BottomNavigationBar组件设置给Scaffold组件的bottomNavigationBar属性
- 将四个BottomNavigationBarItem组件存放到BottomNavigationBar组件的items属性

注意点:
- items属性元素个数必须大于或等于2个
- items属性元素个数如果大于3个,则底部导航样式要使用type属性调整为fixed
处理交互-使用底部导航切换页面内容
- 切换底部导航
- 先监听底部导航的点击事件,并获取点击的Item索引
- 再将获取的Item索引赋值给BottomNavigationBar组件的currentIndex属性
- 最后刷新底部导航,更新currentIndex属性的值
- 切换页面内容
- 使用Item索引值从页面列表中读取出对应的页面组件展示即可


处理交互-优化底部导航交互效果
- 去除点击和长按时的背景色
- 使用Theme组件可以自定义组件主题样式
- 自定义底部导航的主题样式,设置点击和长按时的背景色为透明色
- 统一选中和未选中状态的字号
- 选中状态的字号:selectedFontSize属性
- 未选中状态的字号:unselectedFontSize属性
优化底部导航图标和文字
- 准备底部导航设计稿图标
- 存放底部导航图标到assets文件目录
- 指定底部导航图标加载路径
- 展示底部导航设计稿图标
- 选中状态的图标: activeIcon属性
- 未选中状态的图标:icon属性
- 设置选中和未选中状态的文字颜色
- 选中状态的颜色:selectedItemColor属性
- 未选中状态的颜色:unselectedItemColor属性
解决切换底部导航Item时图标闪动的问题
- 问题:底部导航初次切换Item时,图标会闪一下,再次切换就正常
- 原因:
- Image组件在加载新图时,默认会先将旧图清空,在新图展示前,会有一段空白内容
- 如果加载新图有延迟,则空白内容就会明显展示出来,此时就会看到图标闪动的画面
- 解决办法:
- gaplessPlayback属性: 控制Image组件在加载新图时是否清空旧图
- false:加载新图时,先将旧图清空,在新图展示前,会有一段空白内容
- true:加载新图时,不清空旧图,直到新图展示出来为止

完整代码 root_page.dart
import 'package:erabbit_app/pages/cart/cart_page.dart';
import 'package:erabbit_app/pages/home/home_page.dart';
import 'package:erabbit_app/pages/category/category_page.dart';
import 'package:erabbit_app/pages/mine/mine_page.dart';
import 'package:flutter/material.dart';
class RootPage extends StatefulWidget {
@override
_RootPageState createState() => _RootPageState();
}
class _RootPageState extends State<RootPage> {
List pages = [HomePage(), CategoryPage(), CartPage(), MinePage()];
int _currentIndex = 0;
@override
Widget build(BuildContext context) {
return Scaffold(
body: pages[_currentIndex],
bottomNavigationBar: Theme(
data: ThemeData(
splashColor: Colors.transparent,
highlightColor: Colors.transparent,
),
child: BottomNavigationBar(
currentIndex: _currentIndex,
onTap: (int index) {
setState(() {
_currentIndex = index;
});
},
selectedFontSize: 10.0,
unselectedFontSize: 10.0,
selectedItemColor: Color(0xff3cceaf),
unselectedItemColor: Color(0xff383838),
type: BottomNavigationBarType.fixed,
items: [
BottomNavigationBarItem(
icon: Image.asset(
'assets/home_nor.png',
gaplessPlayback: true,
),
activeIcon: Image.asset(
'assets/home_sel.png',
gaplessPlayback: true,
),
label: '首页',
),
BottomNavigationBarItem(
icon: Image.asset(
'assets/category_nor.png',
gaplessPlayback: true,
),
activeIcon: Image.asset(
'assets/category_sel.png',
gaplessPlayback: true,
),
label: '分类',
),
BottomNavigationBarItem(
icon: Image.asset(
'assets/cart_nor.png',
gaplessPlayback: true,
),
activeIcon: Image.asset(
'assets/cart_sel.png',
gaplessPlayback: true,
),
label: '购物车',
),
BottomNavigationBarItem(
icon: Image.asset(
'assets/mine_nor.png',
gaplessPlayback: true,
),
activeIcon: Image.asset(
'assets/mine_sel.png',
gaplessPlayback: true,
),
label: '我的',
),
],
),
),
);
}
}