Compose 中要在不同頁面之間切換,可以用 Navigation API。今天就來用在專案中
dependencies {
implementation "androidx.navigation:navigation-compose:2.5.2"
}
NavController 是本次的主角,要創建他可以使用 rememberNavController 。這個 API 提供我們換頁的方法和有返回上頁的[currentBackStackEntryAsState()](https://developer.android.com/reference/kotlin/androidx/navigation/compose/package-summary#(androidx.navigation.NavController).currentBackStackEntryAsState())
val navController = rememberNavController()
NavHost 就像是目錄,這裡會羅列出所有頁面的路徑。
NavHost 需要前面用 rememberNavController() 建立的 navController ,以及 startDestination 紀錄了起始頁面的路徑名稱。
最後一個參數 builder 可以在 lambda 內部使用 composable("rote"){} 來呈現一個頁面。
“rote” 是頁面路徑的名稱,而composable 的 {} lambda 可以擺上之前做好的頁面 composable function。
val navController =rememberNavController()
NavHost(navController = navController, startDestination = "home"){
composable("home"){
MainScreen() //main page 的 composable function
}
composable("search"){
}
composable("training"){
}
}
要換頁的話要用到 navController 的 navigate() 裡面帶入要去頁面路徑名稱。
navController.navigate("search")
既然會很常用到路徑名稱,我就可以考慮把路徑提取出來作做成 enum 方便管理。
enum class NavPath {
Main, Search, Training
}
val navController =rememberNavController()
NavHost(navController = navController, startDestination = NavPath.Main.name) {
composable(NavPath.Main.name) { MainScreen() }
composable(NavPath.Search.name) { SearchScreen() }
composable(NavPath.Training.name) { TrainingScreen() }
}
在這個 APP 中有幾個跳轉路徑
MainScreen 可以跳轉到 SearchScreen 或 TrainingScreen 。
SearchScreen 可以返回 MainScreen 或 進到搜尋結果的 TrainingScreen。
TrainingScreen 則是可以回到上一頁。
舉 Main Screen 的參數例子
fun MainScreen(
onSearchBarClick : () -> Unit,
onAddTrainingClick : () -> Unit,
onTrainingClick : () -> Unit,
) {
//...
}
用在外 NavHost 就是這樣
NavHost(navController = navController, startDestination = NavPath.Main.name) {
composable(NavPath.Main.name) {
MainScreen(
onSearchBarClick = { /*TODO*/ },
onAddTrainingClick = { /*TODO*/ },
onTrainingClick = { /*TODO*/ }
)
}
composable(NavPath.Search.name) { SearchScreen() }
composable(NavPath.Training.name) { TrainingScreen() }
}
接下來就可以在 onSearchBarClick 的 lambda 中執行換頁。
composable(NavPath.Main.name) {
MainScreen(
onSearchBarClick = { navController.navigate(NavPath.Search.name) },
onAddTrainingClick = { navController.navigate(NavPath.Training.name) },
onTrainingClick = { navController.navigate(NavPath.Training.name) }
)
//...
}
要返回上一頁可以使用 navController 的 popBackStack()
navController.popBackStack()
首先在 SearchScreen 和 TrainingScreen 新增 back 參數,用來傳遞回上一頁的 funtion
@Composable
fun SearchScreen(
back: () -> Unit
) {
//...
}
在 NavHost 使用時將 navController.popBackStack() 傳入 back lambda
NavHost(navController = navController, startDestination = NavPath.Main.name) {
//...
composable(NavPath.Search.name) { SearchScreen(back = { navController.popBackStack() }) }
//...
}
今天學會了 navigtion 的基本換頁功能,明天繼續探討 popup 和 換頁時要怎麼帶參數。
今日運動
深蹲
40kg 15 15 15
50kg 10 8 12
45kg 8 8 8
槓鈴肩推
15kg 12 8 8 8
(熬夜 使人體力退步)