iT邦幫忙

2025 iThome 鐵人賽

DAY 14
0
Mobile Development

現代Android jetpack compose開發入門系列 第 14

Day 14:套用Scaffold,結合導覽功能

  • 分享至 

  • xImage
  •  

這個部分有兩篇,分別是使用Scaffold與將導覽功能融入

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當作導覽列

Bottom navigation

我這邊使用的是導覽的一系列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的功能,這邊是一般的主頁面會用的配置,我分別說明

  • navigate 導覽到指定位置
  • popUpTo 將導覽圖中的其他小頁面都清除,並保留狀態
  • launchingSingleTop 讓同一個頁面在途中只會有一個
  • restoreState 讓再次造訪這個頁面的時候會返回當初的狀態

注:restoreState與saveState這裡有坑,如果你想要用一個只能進去不能出來的頁面,讓使用者通過點擊下方的導覽來脫離,那會出問題,因為這個頁面已經記得他進入了出不來的頁面,所以會卡死在裡面


上一篇
Day 13:靈活的切換頁面
下一篇
Day 15:將導覽套用在應用上
系列文
現代Android jetpack compose開發入門15
圖片
  熱門推薦
圖片
{{ item.channelVendor }} | {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言