底部导航栏是一个常见的组件,用于快速切换应用中的不同视图。Flutter 提供了 BottomNavigationBar
组件,它是一个遵循 Material Design 规范的底部导航栏,支持文本、图标或两者结合的导航项。
编辑
组件特性
BottomNavigationBar
组件具有以下特性:
- 支持三到五个顶级视图的快速切换。
- 可以与
Scaffold
组件结合使用。 - 支持自定义导航项的图标、标签和颜色。
组件属性
BottomNavigationBar
组件提供了多种属性来自定义其外观和行为:
BottomNavigationBar({
super.key,
required this.items,
this.onTap,
this.currentIndex = 0,
this.elevation,
this.type,
Color? fixedColor,
this.backgroundColor,
this.iconSize = 24.0,
Color? selectedItemColor,
this.unselectedItemColor,
this.selectedIconTheme,
this.unselectedIconTheme,
this.selectedFontSize = 14.0,
this.unselectedFontSize = 12.0,
this.selectedLabelStyle,
this.unselectedLabelStyle,
this.showSelectedLabels,
this.showUnselectedLabels,
this.mouseCursor,
this.enableFeedback,
this.landscapeLayout,
this.useLegacyColorScheme = true,
})
每个参数的详细解释和使用方式:
- key: 用于控制导航栏的
GlobalKey
。如果导航栏在整个应用中是唯一的,可以使用UniqueKey
。 - items: 必须提供的一个
List<BottomNavigationBarItem>
,每个BottomNavigationBarItem
代表导航栏中的一个项目,包括图标、标题等。 - onTap: 一个回调函数,当用户点击导航栏中的任一项时触发。参数是被点击项的索引。
- currentIndex: 初始选中项的索引,默认为
0
。使用这个属性可以控制哪个导航项在初始化时被选中。 - elevation: 表示导航栏的阴影效果,数值越大,阴影越明显。
- type: 导航栏的类型,可以是
BottomNavigationBarType.fixed
或BottomNavigationBarType.shifting
。如果不指定,默认值根据items
的数量自动决定。 - fixedColor: 当
type
为BottomNavigationBarType.fixed
时,用于设置未选中项的颜色。如果不设置,将使用主题中的颜色。 - backgroundColor: 导航栏的背景颜色。如果不设置,将使用主题中的背景颜色。
- iconSize: 导航项图标的大小,默认值为
24.0
。 - selectedItemColor: 选中项的颜色。如果不设置,将使用主题中的颜色。
- unselectedItemColor: 未选中项的颜色。如果不设置,将使用主题中的颜色。
- selectedIconTheme: 选中项图标的主题,可以用来设置选中图标的亮度、大小等。
- unselectedIconTheme: 未选中项图标的主题,可以用来设置未选中图标的亮度、大小等。
- selectedFontSize: 选中项文本的字体大小,默认为
14.0
。 - unselectedFontSize: 未选中项文本的字体大小,默认为
12.0
。 - selectedLabelStyle: 选中项文本的样式,可以用来自定义字体、颜色等。
- unselectedLabelStyle: 未选中项文本的样式。
- showSelectedLabels: 是否显示选中项的文本标签,默认为
true
。 - showUnselectedLabels: 是否显示未选中项的文本标签,默认为
true
。 - mouseCursor: 鼠标悬停在导航项上时的光标样式。
- enableFeedback: 是否启用点击反馈。当设置为
true
时,点击导航项会有水波纹效果 - landscapeLayout: 横屏布局配置,可以是
BottomNavigationBarLandscapeLayout.centered
或BottomNavigationBarLandscapeLayout.behavior
。 - useLegacyColorScheme: 是否使用旧版的颜色方案。默认为
true
。在某些情况下,如果你希望导航栏的颜色与旧版本的 Flutter 主题兼容,可以设置为true
。
导航栏类型
Flutter 提供了两种导航栏类型:
BottomNavigationBarType.fixed
:适用于少于四个导航项的情况。BottomNavigationBarType.shifting
:适用于四个或更多导航项的情况。
BottomNavigationBarType.fixed
- 适用场景:当导航项少于四个时,推荐使用
BottomNavigationBarType.fixed
。 视觉表现:
- 所有导航项在导航栏上均匀分布。
- 选中的导航项会突出显示,可以通过
selectedItemColor
属性自定义选中项的颜色。 - 未选中的导航项颜色较淡,可以通过
unselectedItemColor
属性自定义颜色。 - 通常,选中项的图标和文本都会显示,而未选中项可能只显示图标,或者图标和文本颜色较淡。
特点:
- 提供了一种稳定且一致的导航体验。
- 适合那些需要用户在少数几个主要功能间频繁切换的应用。
编辑
BottomNavigationBarType.shifting
- 适用场景:当导航项有四个或更多时,推荐使用
BottomNavigationBarType.shifting
。 视觉表现:
- 导航项的布局会根据当前选中项动态变化,未选中的项会被压缩,给选中项留出更多空间。
- 选中的导航项不仅图标和文本颜色会改变,其图标也可能会有动画效果,如放大或改变形状。
- 背景颜色会根据选中项的
backgroundColor
属性变化,使得选中项更加突出。
特点:
- 提供了更加动态和响应式的导航体验。
- 适合那些有多个导航项,且希望给当前选中项更多视觉重点的应用。
编辑
自定义样式
自定义 BottomNavigationBar
的样式包括颜色、形状和大小。你可以通过设置 backgroundColor
、elevation
和 shape
属性来实现。
BottomNavigationBar(
// 导航项数组
items: _navItems,
// 当前选中项的索引
currentIndex: _currentIndex,
// 点击导航项时触发的回调函数
onTap: _onItemTapped,
// 自定义选中项的颜色
selectedItemColor: Colors.blue,
// 自定义未选中项的颜色
unselectedItemColor: Colors.grey,
// 导航栏的背景颜色
backgroundColor: Colors.white,
// 导航栏的阴影大小
elevation: 8,
// 导航栏的形状,这里设置为圆角
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(20.0),
),
// 自定义选中项的图标主题
selectedIconTheme: IconThemeData(
size: 30.0, // 选中图标大小
),
// 自定义未选中项的图标主题
unselectedIconTheme: IconThemeData(
size: 25.0, // 未选中图标大小
),
// 自定义选中项的文字样式
selectedLabelStyle: TextStyle(
fontSize: 14.0, // 选中文字大小
fontWeight: FontWeight.bold, // 文字加粗
),
// 自定义未选中项的文字样式
unselectedLabelStyle: TextStyle(
fontSize: 12.0, // 未选中文字大小
),
);
与页面状态同步
使用 BottomNavigationBar
控制页面跳转时,需要确保导航栏的状态与当前页面状态同步。这通常通过设置 BottomNavigationBar
的 currentIndex
属性来实现。
定义 onTap
回调函数来更新当前选中项的索引:
void _onItemTapped(int index) {
setState(() {
_currentIndex = index;
});
}
动画效果
BottomNavigationBar
支持平滑的视图切换动画。当用户点击不同的导航项时,页面会平滑地切换,提供流畅的用户体验。
要实现更复杂的动画效果,你可能需要使用 AnimatedBuilder
、AnimationController
和其他动画相关的Flutter组件。例如淡入淡出、缩放等。以下是一个简单的淡入淡出动画示例:
#使用 AnimatedBuilder 包裹 PageView 或者其他视图组件,根据 _currentIndex 来构建页面
AnimatedBuilder(
animation: _animationController,
builder: (BuildContext context, Widget child) {
return PageView(
children: _pages,
controller: PageController(initialPage: _currentIndex),
physics: NeverScrollableScrollPhysics(),
);
},
)
#添加动画效果
List<FadeTransition> _createFadeTransitions() {
return _navItems.map((item) => FadeTransition(
opacity: Tween(begin: 0.0, end: 1.0).animate(_animationController),
child: item,
)).toList();
}
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。