Compose Navigation快速入门

  • [1. 引入Navigation](#1. 引入Navigation)
    • [1.1 libs.version.toml](#1.1 libs.version.toml)
    • [1.2. build.gradle.kts](#1.2. build.gradle.kts)
  • [2. 主要代码如下](#2. 主要代码如下)
    • [2.1 MainHost.kt](#2.1 MainHost.kt)
    • [2.2 SettingViewModel.kt](#2.2 SettingViewModel.kt)

1. 引入Navigation

1.1 libs.version.toml

kotlin 复制代码
[versions]
agp = "8.6.0"
kotlin = "1.9.0"
coreKtx = "1.10.1"
junit = "4.13.2"
junitVersion = "1.1.5"
espressoCore = "3.5.1"
lifecycleRuntimeKtx = "2.6.1"
activityCompose = "1.8.0"
composeBom = "2024.04.01"

navHost = "2.8.0"
kotlinxSerializationJson = "1.6.3"
androidxLifecycle = "2.8.5"

[libraries]
androidx-core-ktx = { group = "androidx.core", name = "core-ktx", version.ref = "coreKtx" }
junit = { group = "junit", name = "junit", version.ref = "junit" }
androidx-junit = { group = "androidx.test.ext", name = "junit", version.ref = "junitVersion" }
androidx-espresso-core = { group = "androidx.test.espresso", name = "espresso-core", version.ref = "espressoCore" }
androidx-lifecycle-runtime-ktx = { group = "androidx.lifecycle", name = "lifecycle-runtime-ktx", version.ref = "lifecycleRuntimeKtx" }
androidx-activity-compose = { group = "androidx.activity", name = "activity-compose", version.ref = "activityCompose" }
androidx-compose-bom = { group = "androidx.compose", name = "compose-bom", version.ref = "composeBom" }
androidx-ui = { group = "androidx.compose.ui", name = "ui" }
androidx-ui-graphics = { group = "androidx.compose.ui", name = "ui-graphics" }
androidx-ui-tooling = { group = "androidx.compose.ui", name = "ui-tooling" }
androidx-ui-tooling-preview = { group = "androidx.compose.ui", name = "ui-tooling-preview" }
androidx-ui-test-manifest = { group = "androidx.compose.ui", name = "ui-test-manifest" }
androidx-ui-test-junit4 = { group = "androidx.compose.ui", name = "ui-test-junit4" }
androidx-material3 = { group = "androidx.compose.material3", name = "material3" }
// Navigation
androidx-navigation = { group = "androidx.navigation", name = "navigation-compose",version.ref = "navHost" }
// 序列化包
kotlinx-serialization-json = { group = "org.jetbrains.kotlinx", name = "kotlinx-serialization-json", version.ref = "kotlinxSerializationJson" }
androidx-lifecycle-viewModelCompose = { group = "androidx.lifecycle", name = "lifecycle-viewmodel-compose", version.ref = "androidxLifecycle" }

[plugins]
android-application = { id = "com.android.application", version.ref = "agp" }
kotlin-android = { id = "org.jetbrains.kotlin.android", version.ref = "kotlin" }
// 序列化插件
kotlin-serialization = { id = "org.jetbrains.kotlin.plugin.serialization", version.ref = "kotlin" }

1.2. build.gradle.kts

kts 复制代码
plugins {
    alias(libs.plugins.android.application)
    alias(libs.plugins.kotlin.android)
    id("kotlinx-serialization")
}

android {
    namespace = "com.hjq.composenavhost"
    compileSdk = 34

    defaultConfig {
        applicationId = "com.hjq.composenavhost"
        minSdk = 24
        targetSdk = 34
        versionCode = 1
        versionName = "1.0"

        testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner"
        vectorDrawables {
            useSupportLibrary = true
        }
    }

    buildTypes {
        release {
            isMinifyEnabled = false
            proguardFiles(
                getDefaultProguardFile("proguard-android-optimize.txt"),
                "proguard-rules.pro"
            )
        }
    }
    compileOptions {
        sourceCompatibility = JavaVersion.VERSION_1_8
        targetCompatibility = JavaVersion.VERSION_1_8
    }
    kotlinOptions {
        jvmTarget = "1.8"
    }
    buildFeatures {
        compose = true
    }
    composeOptions {
        kotlinCompilerExtensionVersion = "1.5.1"
    }
    packaging {
        resources {
            excludes += "/META-INF/{AL2.0,LGPL2.1}"
        }
    }
}

dependencies {

    implementation(libs.androidx.core.ktx)
    implementation(libs.androidx.lifecycle.runtime.ktx)
    implementation(libs.androidx.activity.compose)
    implementation(platform(libs.androidx.compose.bom))
    implementation(libs.androidx.ui)
    implementation(libs.androidx.ui.graphics)
    implementation(libs.androidx.ui.tooling.preview)
    implementation(libs.androidx.material3)
    implementation(libs.androidx.navigation)
    implementation(libs.kotlinx.serialization.json)
    implementation(libs.androidx.lifecycle.viewModelCompose)

    testImplementation(libs.junit)
    androidTestImplementation(libs.androidx.junit)
    androidTestImplementation(libs.androidx.espresso.core)
    androidTestImplementation(platform(libs.androidx.compose.bom))
    androidTestImplementation(libs.androidx.ui.test.junit4)
    debugImplementation(libs.androidx.ui.tooling)
    debugImplementation(libs.androidx.ui.test.manifest)
}

2. 主要代码如下

2.1 MainHost.kt

kotlin 复制代码
// 参数序列化
@Serializable
data class HomeRoute(val name: String)

@Serializable
data class SettingRoute(val userId: String)

@Serializable
object ConfigDialog


@Composable
fun MainHost(modifier: Modifier) {
    Box(modifier = modifier.fillMaxSize()) {
        val navController = rememberNavController()
        NavHost(navController = navController,
            // 开始入口
            startDestination = HomeRoute(name = "Kim"),
            // 进入动画
            enterTransition = {
                slideInHorizontally(animationSpec = tween(300))
            },
            // 移除动画
            exitTransition = {
                slideOutHorizontally(animationSpec = tween(300))
            }) {
            // Home界面
            composable<HomeRoute> { backStackEntry ->
                // 获取上一个界面返回的参数
                val homeRoute: HomeRoute = backStackEntry.toRoute()
                HomeScreenHost(route = homeRoute, onNavSetting = {
                    // 传入下一个界面的参数
                    navController.navigate(route = SettingRoute(userId = "UserId1"))
                }, configDialog = {
                    navController.navigate(route = ConfigDialog)
                })
            }
            // 设置界面
            composable<SettingRoute> {
                SettingScreenHost {
                    // 返回上一界面并带参数
                    navController.navigate(route = HomeRoute("Devi"))
                }
            }
            // 配置Dialog
            dialog<ConfigDialog> {
                ConfigDialogHost()
            }
        }
    }
}


@Composable
private fun HomeScreenHost(
    route: HomeRoute,
    onNavSetting: () -> Unit,
    configDialog: () -> Unit
) {
    Column(modifier = Modifier.fillMaxSize()) {
        Text(text = route.name)
        Button(onClick = onNavSetting) {
            Text("Go Setting")
        }

        Button(onClick = configDialog) {
            Text("Config Dialog")
        }
    }
}

@Composable
private fun SettingScreenHost(onNavSetting: () -> Unit) {
    val settingViewModel = viewModel(SettingViewModel::class.java)
    Column(modifier = Modifier.fillMaxSize()) {
        // 获取传入的参数并显示
        Text(text = "Get UserId = ${settingViewModel.getUserId()}")
        Button(onClick = onNavSetting) {
            Text("Back To User")
        }
    }
}

@Composable
private fun ConfigDialogHost() {
    Column(
        modifier = Modifier
            .fillMaxSize()
            .background(Color.White)
    ) {
        Text("Config Dialog")
    }
}

2.2 SettingViewModel.kt

kotlin 复制代码
class SettingViewModel(
    savedStateHandle: SavedStateHandle
) : ViewModel() {

    // 获取上一个界面传入的参数
    private val settingRoute = savedStateHandle.toRoute<SettingRoute>()

    fun getUserId(): String = settingRoute.userId
}
相关推荐
氦客8 天前
Android Compose 显示底部对话框 (ModalBottomSheet),实现类似BottomSheetDialog的效果
android·dialog·ui·compose·modal·bottomsheet·底部对话框
小林爱23 天前
【Compose multiplatform教程06】用IDEA编译Compose Multiplatform常见问题
android·java·前端·kotlin·intellij-idea·compose·多平台
小林爱25 天前
【Compose multiplatform教程12】【组件】Box组件
前端·kotlin·android studio·框架·compose·多平台
俺不理解1 个月前
Android Compose 悬浮窗
android·生命周期·compose·悬浮窗
H.ZWei1 个月前
鸿蒙ZRouter动态路由框架—服务路由
harmonyos·鸿蒙·navigation·router
特立独行的猫a1 个月前
HarmonyOS NEXT的Navigation,跳转子页面后底部Tab不隐藏问题解决
开发语言·前端·javascript·harmonyos·navigation
大熊猫侯佩2 个月前
SwiftUI 列表(或 Form)子项中的 Picker 引起导航无法跳转的原因及解决
list·swiftui·form·列表·navigation·导航·picker
梁辰兴2 个月前
Android Studio 使用插件Database Navigation 连接 sqlite数据库
数据库·sqlite·android studio·database·navigation·plugins
许多仙2 个月前
【Android Compose原创组件】可拖动滚动条的完美实现
android·compose·scrollbar·compose快速滚动条