Navigasi 3

Navigation 3 adalah library navigasi yang didesain dari awal untuk Jetpack Compose. Panduan ini menjelaskan cara menerapkan Navigation 3 di aplikasi Wear OS.

Konsep Inti

  • NavKey: ID serialisasi dan aman jenis untuk tujuan (layar) di aplikasi Anda.
  • NavBackStack: Daftar instance NavKey yang dapat berubah yang merepresentasikan histori navigasi. Anda mendorong dan memunculkan item langsung dari daftar ini.
  • rememberNavBackStack: Composable yang membuat dan mempertahankan tumpukan kembali di seluruh perubahan konfigurasi dan penghentian proses.
  • NavDisplay: Komponen UI inti yang mengamati stack kembali dan merender layar aktif.
  • EntryProvider: DSL pemetaan yang menautkan NavKey ke UI @Composable yang sebenarnya.
  • SwipeDismissableSceneStrategy: Strategi khusus Wear yang membungkus layar Anda dalam gestur geser untuk menutup dan menangani animasi kembali bawaan.

Langkah 1: Tambahkan dependensi

Tambahkan dependensi Navigation 3, Wear Compose, dan Serialization yang diperlukan ke project Anda.

Groovy

dependencies {
    // Core Navigation 3 APIs
    implementation "androidx.navigation3:navigation3-runtime:1.2.0-alpha02"
    implementation "androidx.navigation3:navigation3-ui:1.2.0-alpha02"

    // Wear OS specific Navigation 3 integration
    implementation "androidx.wear.compose:compose-navigation3:1.6.1"

    // Kotlinx Serialization for type-safe routing
    implementation "org.jetbrains.kotlinx:kotlinx-serialization-json:1.10.0"
}

Kotlin

dependencies {
    // Core Navigation 3 APIs
    implementation("androidx.navigation3:navigation3-runtime:1.2.0-alpha02")
    implementation("androidx.navigation3:navigation3-ui:1.2.0-alpha02")

    // Wear OS specific Navigation 3 integration
    implementation("androidx.wear.compose:compose-navigation3:1.6.1")

    // Kotlinx Serialization for type-safe routing
    implementation("org.jetbrains.kotlinx:kotlinx-serialization-json:1.10.0")
}

Langkah 2: Tentukan tujuan (NavKey)

Layar ditentukan sebagai objek atau class data yang dapat diserialisasi dan memiliki jenis yang kuat yang mengimplementasikan antarmuka NavKey.

@Serializable
sealed interface Screen : NavKey {
    @Serializable
    data object Home : Screen

    @Serializable
    data class Details(val itemId: String) : Screen
}

Langkah 3: Siapkan NavDisplay dan stack kembali

Di root aplikasi Anda, inisialisasi stack kembali dan strategi adegan Wear OS, lalu hubungkan ke NavDisplay.

// 1. Create the persistent back stack starting at the Home screen
val backStack = rememberNavBackStack(Screen.Home)

// 2. Initialize the Wear OS swipe-to-dismiss strategy
val strategy = rememberSwipeDismissableSceneStrategy<NavKey>()

// 3. Render the NavDisplay
NavDisplay(
    backStack = backStack,
    sceneStrategies = listOf(strategy),
    entryProvider = entryProvider {
        // 4. Map keys to Composables
        entry<Screen.Home> {
            HomeScreen(
                onNavigateToDetails = { id -> backStack.add(Screen.Details(id)) }
            )
        }
        entry<Screen.Details> { key ->
            DetailsScreen(
                itemId = key.itemId,
                onBack = { backStack.removeAt(backStack.lastIndex) }
            )
        }
    }
)

Langkah 4: Lakukan tindakan navigasi

Karena data sebelumnya hanyalah MutableList yang disesuaikan, navigasi menjadi sangat mudah. Anda melakukan operasi langsung pada instance backStack:

  • Maju: backStack.add(Screen.Details("123"))
  • Kembali: backStack.removeLast() atau backStack.removeLastOrNull()
  • Hapus dan Reset: backStack.clear(); backStack.add(Screen.Home) (atau gunakan operasi daftar untuk mengganti stack).

Langkah 5: (Opsional) Menentukan cakupan ViewModel ke tujuan

Secara default, ViewModel dicakup ke Activity. Navigation 3 menyediakan artefak tertentu (lifecycle-viewmodel-navigation3) untuk mencakup ViewModel secara aman ke NavEntry di data sebelumnya. Saat tujuan dikeluarkan dari data sebelumnya, ViewModel akan dihapus.

  1. Tambahkan dependensi:

    implementation("androidx.lifecycle:lifecycle-viewmodel-navigation3:...")
    
  2. Tambahkan dekorator penyimpanan ViewModel ke NavDisplay entryDecorators. Anda juga harus menyertakan SaveableStateHolderNavEntryDecorator secara eksplisit saat memberikan decorator kustom untuk mempertahankan status Compose rememberSaveable:

    NavDisplay(
        backStack = backStack,
        sceneStrategies = listOf(strategy),
        entryDecorators = listOf(
            rememberSaveableStateHolderNavEntryDecorator(),
            rememberViewModelStoreNavEntryDecorator()
        ),
        entryProvider = entryProvider {
            entry<Screen.Home> {
                // Any viewModel() requested here will be scoped to this NavEntry
                val viewModel: HomeViewModel = viewModel()
            }
        }
    )