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
(熬夜 使人體力退步)