Kotlin Practice # 12 Compose Bottom Bar Navigation 底部導航初探

Dogpa Chen
9 min readApr 9, 2023

上一篇學習了多彩文字的用法,讓一行文字能夠快速的產出不同的顏色。

這篇則要開始將原本iOS的尋露APP,建立Android的版本,因為是自己的side project,所以會透過Jetpack Compose來完成。首先要來學習的是下方的Bottom Bar Navigation,使用者可以透過Bottom Bar快速的點擊頁面。

首先是建立一個PageView,可帶入標題與背景顏色做切換,後續要顯示不同的四個分頁。

@Composable
fun PageView(title:String, background: Color) {
Box(
modifier = Modifier
.fillMaxSize()
.background(background),
contentAlignment = Alignment.Center
) {
Text(
text = title,
fontSize = MaterialTheme.typography.h3.fontSize,
fontWeight = FontWeight.Bold,
color = Color.Black
)
}
}

接著建立sealed Class來準備放入後續需要使用的Bottom需要的route、顯示分類文字、Icon與顯示的顏色,因為sealed的關係,我們可以透過object先建立好四個會用到的項目。

sealed class BottomBarScreenView(
val route: String,
val title: String,
val color: Color,
val iconInt: Int
) {
object List : BottomBarScreenView(
route = "list",
title = "列表",
color = Color.Green,
iconInt = R.drawable.baseline_format_list_bulleted_24
)
object Map : BottomBarScreenView(
route = "map",
title = "地圖",
color = Color.Red,
iconInt = R.drawable.outline_location_on_24
)
object Favorite : BottomBarScreenView(
route = "favorite",
title = "最愛",
color = Color.Blue,
iconInt = R.drawable.baseline_favorite_24
)
object Other : BottomBarScreenView(
route = "other",
title = "其他",
color = Color.Yellow,
iconInt = R.drawable.baseline_light_mode_24
)
}

接續是建立一個是BottomNavGraphView裡面透過NavHost放入列表、地圖、最愛、其他四個View。

@Composable
fun BottomNavGraphView(navController: NavHostController) {
NavHost(
navController = navController,
startDestination = BottomBarScreenView.List.route
) {
composable(route = BottomBarScreenView.List.route) {
PageView("列表",Color.Green)
}
composable(route = BottomBarScreenView.Map.route) {
PageView("地圖",Color.Red)
}
composable(route = BottomBarScreenView.Favorite.route) {
PageView("最愛",Color.Blue)
}
composable(route = BottomBarScreenView.Other.route) {
PageView("其他",Color.Yellow)
}
}
}

接續建立一個BottomBar,裡面建立一個screens陣列存放上面建立好的BottomBarScreenView,透過BottomNavigation內的迴圈將四個分類頁面加入到AddItem內。

另外透過RowScope.AddItem來寫入點擊行為、調整UI、更換route的功能。BottomBar的被選擇的顏色的改變基本上就是在這裡完成。



@Composable
fun BottomBar(navController: NavHostController) {
val screens = listOf(
BottomBarScreenView.List,
BottomBarScreenView.Map,
BottomBarScreenView.Favorite,
BottomBarScreenView.Other,
)
val navBackStackEntry by navController.currentBackStackEntryAsState()
val currentDestination = navBackStackEntry?.destination
BottomNavigation {
screens.forEach { screen ->
AddItem(
screen = screen,
currentDestination = currentDestination,
navController = navController
)
}
}
}


@Composable
fun RowScope.AddItem(
screen: BottomBarScreenView,
currentDestination: NavDestination?,
navController: NavHostController
) {
val selected = currentDestination?.hierarchy?.any { it.route == screen.route } == true
BottomNavigationItem(
modifier = Modifier.background(Color.White),
label = {
Text(text = screen.title, color = if (selected) screen.color else Color.Gray)
},
icon = {
Icon(
imageVector = ImageVector.vectorResource(id = screen.iconInt),
contentDescription = "Navigation Icon",
tint = if (selected) screen.color else Color.Gray
)
},
selected = currentDestination?.hierarchy?.any {
it.route == screen.route
} == true,
onClick = {
navController.navigate(screen.route) {
popUpTo(navController.graph.findStartDestination().id)
launchSingleTop = true
}
}
)
}

接續建立一個MainView,透過Scaffold的佈局建立bottomBar,將BottomBar與BottomNavGraphView加入到MainView內。

@Composable
fun MainView() {
val navController = rememberNavController()
Scaffold(
bottomBar = { BottomBar(navController = navController) }
) {
BottomNavGraphView(navController = navController)
}
}

最後將MainView加入到MainActivity內

class MainActivity : ComponentActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContent {
KP12BottomBarTheme {
Surface(
modifier = Modifier.fillMaxSize()
) {
MainView()
}
}
}
}
}

嘗試看一下效果

以上就是關於BottomBar Navigation的學習,side project也算是邁進了一步。持續加油!!!

--

--