Bottom Navigation — 一种导航模式,其中切换部分的面板位于屏幕底部。在Android中通过BottomNavigationView(Material 3)实现,在iOS中通过UITabBarController或SwiftUI中的TabView实现。有关Material Design规范的更多详情,请参阅Material Design 3文档。
要点
Bottom Navigation — 一种导航模式,应用的主要部分通过屏幕底部的面板进行访问。这种模式由于单手操作的便利性而成为移动设计的标准。与侧边菜单(Drawer)不同,Bottom Navigation始终可见,不需要额外的手势来打开。
Material Design 3(2026)将Navigation Bar定义为具有三种状态的组件:default(图标+标签)、labeled(放大的标签,一个活动选项卡)和unlabeled(仅图标)。Google建议将Navigation Bar用于具有3–5个同等重要部分的应用。对于6个以上部分 — 使用Navigation Drawer。在iOS SwiftUI中,TabView自动使用系统样式的底部面板。
UX Movement(2025)的研究表明:与滑动菜单相比,Bottom Navigation将任务完成时间提高了27%,因为用户无需额外操作即可看到所有可用部分。错误点击次数减少了34%,这得益于较大的触摸目标(Android上至少48x48 dp,iOS上44x44 pt)。
BottomNavigationView在Android中 — 来自Material 3 Library(com.google.android.material.navigation.NavigationBarView)的组件。它取代了Material 2中过时的BottomNavigationView,并增加了对Material You动态颜色、活动选项卡动画指示器和内置徽章的支持。该组件通过XML菜单进行配置,并与Navigation Component完全兼容。
// 使用BottomNavigationView和NavHostFragment的Activity
class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
val navView = findViewById<NavigationBarView>(R.id.nav_view)
val navController = findNavController(R.id.nav_host_fragment)
// 导航自动同步
navView.setupWithNavController(navController)
// 徽章配置
val badge = navView.getOrCreateBadge(R.id.navigation_messages)
badge.number = 8
badge.badgeGravity = BadgeDrawable.TOP_END
}
}
// Bottom Navigation的XML菜单 (res/menu/bottom_nav_menu.xml)
// <?xml version="1.0" encoding="utf-8"?>
// <menu xmlns:android="http://schemas.android.com/apk/res/android">
// <item android:id="@+id/navigation_home"
// android:icon="@drawable/ic_home"
// android:title="首页" />
// <item android:id="@+id/navigation_messages"
// android:icon="@drawable/ic_chat"
// android:title="聊天" />
// <item android:id="@+id/navigation_profile"
// android:icon="@drawable/ic_person"
// android:title="个人资料" />
// </menu>Material 3 NavigationBarView支持三种labelVisibilityMode模式:LABEL_VISIBILITY_AUTO(默认 — 标签仅显示在活动选项卡上)、LABEL_VISIBILITY_LABELED(全部显示标签)、LABEL_VISIBILITY_UNLABELED(仅图标)。活动选项卡的动画指示器通过itemActiveIndicatorStyle进行配置,带有自定义涟漪效果。
TabView — SwiftUI内置容器,用于创建底部导航。每个选项卡通过.tabItem修饰符与图标和文本定义。TabView在后台自动创建UITabBarController,并支持本机面板的所有功能:徽章、徽章颜色、切换动画和适应Dynamic Type。
import SwiftUI
struct ContentView: View {
var body: some View {
TabView {
HomeView()
.tabItem {
Label("首页", systemImage: "house.fill")
}
.badge(3)
SearchView()
.tabItem {
Label("搜索", systemImage: "magnifyingglass")
}
NotificationsView()
.tabItem {
Label("通知", systemImage: "bell.fill")
}
.badge("12")
ProfileView()
.tabItem {
Label("个人资料", systemImage: "person.circle.fill")
}
}
}
}TabView支持.badge修饰符(iOS 15+),它接受Int(数字徽章)或String(文本徽章)。徽章颜色可以通过.badgeProminence(.increased)更改 — 使徽章更亮。选项卡切换动画通过.tabViewStyle(.automatic)或自定义样式进行配置。对于程序切换控制,使用带有selection的@State。
Bottom Navigation很少单独使用 — 每个选项卡通常包含一个堆栈导航器(SwiftUI中的NavigationView/NavigationStack,Android中的NavHostFragment)。这种组合为用户提供了对部分的快速访问(Tab)以及每个部分内的深度导航(Stack)。这是生产级应用的标准架构。
struct AppTabView: View {
var body: some View {
TabView {
NavigationStack {
HomeView()
}
.tabItem {
Label("首页", systemImage: "house")
}
NavigationStack {
SearchView()
}
.tabItem {
Label("搜索", systemImage: "magnifyingglass")
}
}
}
}
// HomeView内部 — 堆栈导航
struct HomeView: View {
var body: some View {
List(items) { item in
NavigationLink("\(item.title)", value: item)
}
.navigationDestination(for: Item.self) { item in
ItemDetailView(item: item)
}
}
}在Android中,相同的组合通过每个选项卡的NavHostFragment实现。Navigation Component自动为每个选项卡创建back stack:切换选项卡时堆栈状态被保存,返回时被恢复。这提供了无缝的UX,就像Google的系统应用(Play Market、YouTube)一样。
Material 3(Material You)为Bottom Navigation带来了关键变化 — 从用户壁纸生成的动态颜色。系统从壁纸中提取主色,并创建由5个关键色调组成的调色板。NavigationBarView自动应用这些颜色:活动选项卡获得primary颜色,非活动选项卡获得onSurface variant颜色。
活动选项卡指示器的动画变得流畅:切换时,指示器通过插值动画移动到新选项卡。触摸时的涟漪效果使用secondary颜色。Bottom Navigation在Material 3中还通过itemActiveIndicatorStyle支持自定义动画 — 开发人员可以设置指示器的形状(椭圆形、矩形)、边距和颜色。
<!-- NavigationBarView活动指示器样式 -->
<style name="Widget.MyApp.NavigationBarView.ActiveIndicator"
parent="Widget.Material3.NavigationBarView.ActiveIndicator">
<item name="android:height">32dp</item>
<item name="android:width">64dp</item>
<item name="android:marginHorizontal">8dp</item>
<item name="shapeAppearance">
@style/ShapeAppearance.Material3.Corner.Full
</item>
<item name="color">@color/primary_container</item>
</style>在设计Bottom Navigation时,应考虑可用性研究。NN Group(2026):底部面板的高度至少应为56 dp,触摸目标至少为48 dp。标签文本 — 最多12个字符(拉丁字母)或8个字符(西里尔字母)。活动选项卡不仅应在颜色上有所不同,还应在图标状态上有所不同(filled vs outlined)。
Material Design 3建议以下模式:4个选项卡 — 最适合平静扫描;中间的"+"符号(FloatingActionButton) — 用于主要操作;徽章 — 仅用于用户操作计数器。不建议:使用2个选项卡的Bottom Navigation(更好用Tab Layout),动态更改选项卡顺序,在嵌套屏幕上隐藏面板。
常见问题
Bottom Navigation — 屏幕底部的面板,始终可见,适用于3–5个同等重要的部分。Navigation Drawer — 侧边菜单,通过手势或按钮调用,适用于6个以上部分、设置和次要页面。Drawer隐藏内容,Bottom Navigation则不会。
4个选项卡 — 根据NN Group的数据是最佳数量。3个 — 证明底部面板合理的最小数量。5个 — 所有选项卡仍可区分的最大数量。6个以上需要切换到Navigation Drawer或iOS上的"更多"项。
在Android Material 3中,使用NavigationBarView上的getOrCreateBadge(itemId)。通过badge.number设置数字,通过badgeGravity(TOP_END、TOP_START)设置位置。在iOS SwiftUI中 — 对.tabItem使用.badge(Int)修饰符。在UIKit中 — tabBarItem.badgeValue = "N"。
可以。Material 3 NavigationBarView动画化活动选项卡指示器的移动。SwiftUI TabView使用iOS系统动画。对于内容的自定义动画,使用matchedGeometryEffect(SwiftUI)或Transition(Jetpack Compose)。切换面板本身的动画是系统自带的。
适合,适用于移动优先和PWA。Material Design 3有Web组件Navigation Bar。然而,在桌面端最好使用侧边面板(Side Navigation) — 水平空间允许显示更多项目。桌面端的Bottom Navigation是反模式。
总结
我们将开发一款交钥匙移动应用程序
IT Sectr自2017年以来为初创企业和企业打造iOS和Android应用程序。我们将为您提供咨询并提出最佳解决方案。