Navigazione 3

Navigation 3 è una libreria di navigazione progettata interamente per Jetpack Compose. Questa guida spiega come implementare Navigation 3 nelle applicazioni Wear OS.

Concetti principali

  • NavKey: un identificatore serializzabile e con sicurezza dei tipi per una destinazione (schermata) nella tua app.
  • NavBackStack: un elenco modificabile di istanze NavKey che rappresentano la cronologia di navigazione. Puoi inserire ed eliminare elementi direttamente da questo elenco.
  • rememberNavBackStack: un elemento componibile che crea e mantiene il back stack durante le modifiche alla configurazione e l'interruzione del processo.
  • NavDisplay: il componente UI principale che osserva il back stack e visualizza la schermata attiva.
  • EntryProvider: un DSL di mapping che collega un NavKey alla sua UI @Composable effettiva.
  • SwipeDismissableSceneStrategy: la strategia specifica per Wear che racchiude le schermate in un gesto di scorrimento per chiudere e gestisce le animazioni indietro integrate.

Passaggio 1: aggiungi le dipendenze

Aggiungi le dipendenze richieste di Navigation 3, Wear Compose e Serialization al tuo progetto.

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")
}

Passaggio 2: definisci le destinazioni (NavKeys)

Le schermate sono definite come oggetti o classi di dati serializzabili e con tipo sicuro che implementano l'interfaccia NavKey.

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

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

Passaggio 3: configura NavDisplay e il back stack

Nella radice dell'applicazione, inizializza il back stack e la strategia della scena Wear OS, quindi collegali a 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) }
            )
        }
    }
)

Passaggio 4: esegui le azioni di navigazione

Poiché il back stack è solo un MutableList personalizzato, la navigazione è incredibilmente semplice. Esegui le operazioni direttamente sull'istanza backStack:

  • Vai avanti: backStack.add(Screen.Details("123"))
  • Vai indietro: backStack.removeLast() o backStack.removeLastOrNull()
  • Cancella e reimposta: backStack.clear(); backStack.add(Screen.Home) (oppure utilizza le operazioni di elenco per sostituire lo stack).

Passaggio 5 (facoltativo): definisci l'ambito dei ViewModel per le destinazioni

Per impostazione predefinita, i ViewModel hanno come ambito il Activity. Navigation 3 fornisce un artefatto specifico (lifecycle-viewmodel-navigation3) per definire in modo sicuro l'ambito di un ViewModel per un NavEntry nel back stack. Quando la destinazione viene rimossa dal back stack, il ViewModel viene cancellato.

  1. Aggiungi la dipendenza:

    implementation("androidx.lifecycle:lifecycle-viewmodel-navigation3:...")
    
  2. Aggiungi il decoratore dell'archivio ViewModel a NavDisplay's entryDecorators. Devi anche includere in modo esplicito il SaveableStateHolderNavEntryDecorator quando fornisci decoratori personalizzati per conservare lo stato rememberSaveable di Compose:

    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()
            }
        }
    )