這個部分有兩篇,分別是使用Scaffold與將導覽功能融入
很多的應用都會有Top bar和Bottom bar以及floatingActionButton,讓使用者可以直覺得切換操作與展現應用的特色
這邊借用Android官方的程式碼
@Composable
fun ScaffoldExample() {
var presses by remember { mutableIntStateOf(0) }
Scaffold(
topBar = {
TopAppBar(
colors = topAppBarColors(
containerColor = MaterialTheme.colorScheme.primaryContainer,
titleContentColor = MaterialTheme.colorScheme.primary,
),
title = {
Text("Top app bar")
}
)
},
bottomBar = {
BottomAppBar(
containerColor = MaterialTheme.colorScheme.primaryContainer,
contentColor = MaterialTheme.colorScheme.primary,
) {
Text(
modifier = Modifier
.fillMaxWidth(),
textAlign = TextAlign.Center,
text = "Bottom app bar",
)
}
},
floatingActionButton = {
FloatingActionButton(onClick = { presses++ }) {
Icon(Icons.Default.Add, contentDescription = "Add")
}
}
) { innerPadding ->
Column(
modifier = Modifier
.padding(innerPadding),
verticalArrangement = Arrangement.spacedBy(16.dp),
) {
Text(
modifier = Modifier.padding(8.dp),
text =
"""
This is an example of a scaffold. It uses the Scaffold composable's parameters to create a screen with a simple top app bar, bottom app bar, and floating action button.
It also contains some basic inner content, such as this text.
You have pressed the floating action button $presses times.
""".trimIndent(),
)
}
}
}
他其實就是一個內建的快速介面配置,讓開發者可以更簡單的使用
通常會使用bottom bar當作導覽列
我這邊使用的是導覽的一系列Compose元件
使用navigation compose有不少好處,雖然現在感受不到,但肯定會讓排版元件變簡單
data class BottomNavItem(val title: String, val route: String, val icon: ImageVector)
@Composable
fun BottomBar(navController: NavController, modifier: Modifier = Modifier) {
val bottomBarItems = listOf(
BottomNavItem("首頁", Screens.Main.route, Icons.Default.Home),
BottomNavItem("任務", Screens.TaskInput.route, Icons.Default.Add),
BottomNavItem("設定", Screens.Setting.route, Icons.Default.Settings),
)
NavigationBar {
val navBackEntry by navController.currentBackStackEntryAsState()
val currentRoute = navBackEntry?.destination?.route
bottomBarItems.forEach { item->
NavigationBarItem(
icon = { Icon(item.icon, contentDescription = item.title) },
selected = currentRoute == item.route,
label = { Text(item.title) },
onClick = {
navController.navigate(item.route) {
popUpTo(navController.graph.startDestinationId) { // 回到graph root
saveState = true
}
launchSingleTop = true
if(item.route != Screens.Main.route)
restoreState = true
}
}
)
}
}
}
我先定義了一個data class,方便我使用,其中比較重要的就是navBackEntry和currentRoute,這些都是navigation的功能,讓我們可以知道現在的位置,從而使bottom bar可以知道現在在哪裡
在onclick中,我使用了一些navigate的功能,這邊是一般的主頁面會用的配置,我分別說明
注:restoreState與saveState這裡有坑,如果你想要用一個只能進去不能出來的頁面,讓使用者通過點擊下方的導覽來脫離,那會出問題,因為這個頁面已經記得他進入了出不來的頁面,所以會卡死在裡面