Jetpack Compose 多界面间的路由跳转

更新日期: 2021-09-04 阅读次数: 9843 字数: 544 分类: Android

目录结构

一个简单 Demo 的文件分离结构:

  • Home Screen:首页列表
  • Edit Screen (detail):编辑页
  • NavHost (router):路由定义
  • Main Activity

添加依赖

dependencies {
    implementation "androidx.navigation:navigation-compose:2.4.0-alpha08"
}

添加之后,不要忘了点击 Android Studio 右上角的 Sync Now。 否则像 rememberNavController 这样的函数,无法通过 Alt + Enter 自动添加引用。

注意:同时需要将 build.gradle 中的 compileSdk 和 targetSdk 由 30 修改为 31,否则会报错。 详见下面的编译错误记录。

这个版本号,应该是随时在更新的。如何查看最新的版本号?

navigation-compose 引起的编译报错

在 preview 预览编译时,报错:

FAILURE: Build failed with an exception.

* What went wrong:
Execution failed for task ':app:checkDebugAarMetadata'.
> A failure occurred while executing com.android.build.gradle.internal.tasks.CheckAarMetadataWorkAction
   > One or more issues found when checking AAR metadata values:
     
     The minCompileSdk (31) specified in a
     dependency's AAR metadata (META-INF/com/android/build/gradle/aar-metadata.properties)
     is greater than this module's compileSdkVersion (android-30).
     Dependency: androidx.navigation:navigation-compose:2.4.0-alpha08.

从提示上看是,androidx.navigation:navigation-compose:2.4.0-alpha08 依赖 minCompileSdk 31, 而 build.gradle 中设置的 compileSdk 为 30.

解决方法就是将 compileSdk 和 targetSdk 都由 30 改为 31.

android {
    compileSdk 31

    defaultConfig {
        applicationId "com.sunzhongwei.app"
        minSdk 21
        targetSdk 31

再次编译成功。

NavHost

定义路由:

enum class DemoScreen {
    HomeScreen,
    EditScreen
}

@Composable
fun DemoNavHost(
    navController: NavHostController
) {
    NavHost(
        navController = navController,
        startDestination = DemoScreen.HomeScreen.name
    ) {
        composable(DemoScreen.HomeScreen.name) {
            HomeScreen(navController = navController)
        }
        composable(DemoScreen.EditScreen.name) {
            EditScreen(navController = navController)
        }
    }
}
  • NavController: 记录 path 栈
  • NavHost: 定义多 composable 界面间的路由关系

HomeScreen

定义首页界面 UI, 及操作

@Composable
fun HomeScreen(navController: NavController) {
    Scaffold(
        drawerContent = { /*...*/ },
        topBar = { /*...*/ },
        content = {
            Items(items)
        },
        floatingActionButton = {
            FloatingActionButton(onClick = {
                navController.navigate(ShelfLifeScreen.EditScreen.name)
            }) {
                Icon(Icons.Filled.Add,"")
            }
        } 
    )
}

EditScreen

@Composable
fun EditScreen(navController: NavController) {
    Text(text = "test")
}

MainActivity

class MainActivity : ComponentActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContent {
            ComposeNavigation()
        }
    }
}

@Composable
fun ComposeNavigation() {
    val navController = rememberNavController()

    DemoNavHost(
        navController = navController,
    ) 
}

带有 NavController 的 composable 如何预览

由于 HomeScreen 添加了 NavController 参数,所以预览失效:

No value passed for parameter 'navController'

加上一个参数即可。

@Preview
@Composable
fun PreviewHome() {
    val navController = rememberNavController()
    HomeScreen(navController)
}

参考

tags: Jetpack Compose Jetpack Navigation

关于作者 🌱

我是来自山东烟台的一名开发者,有敢兴趣的话题,或者软件开发需求,欢迎加微信 zhongwei 聊聊, 查看更多联系方式