iT邦幫忙

2022 iThome 鐵人賽

DAY 16
0

隨著功能越來越多,畫面也會越來越多,跳轉畫面與返回也逐漸複雜,所以會使用 Navigation 函式庫統一處理畫面轉換與返回操作,也降低畫面之間的依賴關係。

Official Navigation

官方文件:
https://developer.android.com/jetpack/compose/navigation

多個 Destination 組成 NavGraph,NavHostController 負責控制畫面轉換與返回操作。
每個畫面被稱為 destination,每個 destination 都要設定一個 route 字串,之後控制時就是用 route 字串決定要導向到哪個頁面。
NavGraph 顧名思義它是一張有向圖(圖學的 graph,不是圖片的 image)。

@Composable
fun MainView() {
    val controller = rememberNavController()
    NavHost(
        navController = controller,
        startDestination = "home"
    ) {
        composable("home") { HomeScreen(controller) }
        composable("setting") { SettingScreen() }
    }
}

@Composable
fun HomeScreen(controller: NavHostController) {
    Button(onClick = {
        controller.navigate("setting")
    }) {
        Text("To setting")
    }
}

@Composable
fun SettingScreen() {
    Text("Setting")
}

Compose Destinations

GitHub:
https://github.com/raamcosta/compose-destinations

基於官方 Navigation 函式庫,但它多了程式碼生成器與一些標注,開發者只要在畫面的 composable function 加上標注,它就會生出對應的 NavGraph 與 Destination 物件。

@RootNavGraph(start = true)
@Destination
@Composable
fun HomeScreen(controller: NavHostController) {
    Button(onClick = {
        controller.navigate("setting")
    }) {
        Text("To setting")
    }
}

@Destination
@Composable
fun SettingScreen() {
    Text("Setting")
}

相較於官方的優點是型別安全,判斷跳轉的 destination 是物件而不是字串,而且生成的 destination 物件是 sealed class,可以用 when 獲取 destination 對應的自訂物件。

fun Destination.toMyRoute(): MyRoute = when (this) {
    HomeScreenDestination -> MyRoute.Home
    SettingScreenDestination -> MyRoute.Setting
}

Voyager

GitHub:
https://github.com/adrielcafe/voyager

Voyager 是一個多平台 Compose Navigation 函式庫,因為是多平台的關係,所以不依賴 Android Lifecycle,以 Screen 物件取代 route 字串達成型別安全,不過最後的 commit 跟 release 停留在 5 月,代表這個專案已經不太活躍,所以後來我改用 Compose Destinations。

@Composable
fun MainView() {
    Navigator(HomeScreen) {
        CurrentScreen()
    }
}

object HomeScreen : Screen {
    @Composable
    override fun Content() {
        val navigator = LocalNavigator.currentOrThrow
        Button(onClick = {
            navigator.push(SettingScreen)
        }) {
            Text("To setting")
        }
    }
}

object SettingScreen : Screen {
    @Composable
    override fun Content() {
        Text("Setting")
    }
}

上一篇
Day 15 - 依賴注入
下一篇
Day 17 - Android Kotlin Coroutine
系列文
關於我用 Compose UI 造新輪子這檔事24
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言