L'API Navigation Compose ti consente di spostarti tra i composabili in un'app Compose, sfruttando al contempo il componente, l'infrastruttura e le funzionalità di Jetpack Navigation.
Questa pagina descrive come eseguire la migrazione da una navigazione Jetpack basata su Fragment a Navigatore Compose, nell'ambito della più ampia migrazione dell'interfaccia utente basata sulla vista a Jetpack Compose.
Prerequisiti per la migrazione
Puoi eseguire la migrazione a Compose di navigazione dopo essere in grado di sostituire tutti i tuoi Frammenti con gli elementi componibili corrispondenti dello schermo. Gli elementi componibili dello schermo possono contenere un mix di contenuti di Compose e View, ma tutte le destinazioni di navigazione devono essere componibili per abilitare la migrazione di Navigation Compose. Fino ad allora, devi continuare a utilizzare il componente di navigazione basato su frammenti nel codice base di Compose e della visualizzazione di interoperabilità. Per ulteriori informazioni, consulta la documentazione sull'interoperabilità della navigazione.
L'utilizzo di Componi navigazione in un'app solo di Componi non è un prerequisito. Puoi continuare a utilizzare il componente di navigazione basato su frammenti, a condizione di conservare Frammenti per ospitare i tuoi contenuti componibili.
Passaggi della migrazione
Indipendentemente dal fatto che tu segua la nostra strategia di migrazione consigliata o un altro approccio, raggiungerai un punto in cui tutte le destinazioni di navigazione sono composibili dello schermo, con i frammenti che fungono solo da contenitori composibili. In questa fase, puoi eseguire la migrazione a Navigation Compose.
Se la tua app segue già un pattern di progettazione UDF e la nostra guida all'architettura, la migrazione a Jetpack Compose e Navigation Compose non dovrebbe richiedere ristrutturazioni importanti di altri livelli dell'app, a parte il livello dell'interfaccia utente.
Per eseguire la migrazione a Navigatore Compose, segui questi passaggi:
- Aggiungi la dipendenza di Compose Navigazione alla tua app.
Crea un composable
App-level
e aggiungilo aActivity
come punto di accesso di Compose, sostituendo la configurazione del layout della vista:class SampleActivity : ComponentActivity() { override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) // setContentView<ActivitySampleBinding>(this, R.layout.activity_sample) setContent { SampleApp(/* ... */) } } }
Crea tipi per ogni destinazione di navigazione. Utilizza un
data object
per le destinazioni che non richiedono dati edata class
oclass
per le destinazioni che richiedono dati.@Serializable data object First @Serializable data class Second(val id: String) @Serializable data object Third
Installa
NavController
in una posizione in cui tutti i componenti componibili che devono farvi riferimento abbiano accesso (solitamente all'interno del tuoApp
componibile). Questo approccio segue i principi dell'elevazione dello stato e ti consente di utilizzareNavController
come fonte attendibile per spostarti tra le schermate composable e mantenere la pila di ritorno:@Composable fun SampleApp() { val navController = rememberNavController() // ... }
Crea l'elemento
NavHost
della tua app all'interno del componibileApp
e trasmetti ilnavController
:@Composable fun SampleApp() { val navController = rememberNavController() SampleNavHost(navController = navController) } @Composable fun SampleNavHost( navController: NavHostController ) { NavHost(navController = navController, startDestination = First) { // ... } }
Aggiungi le destinazioni
composable
per creare il grafo di navigazione. Se per ogni schermata è stata eseguita in precedenza la migrazione a Compose, questo passaggio consiste solo nell'estrarre questi composabili della schermata dai frammenti nellecomposable
destinazioni:class FirstFragment : Fragment() { override fun onCreateView( inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle? ): View { return ComposeView(requireContext()).apply { setContent { // FirstScreen(...) EXTRACT FROM HERE } } } } @Composable fun SampleNavHost( navController: NavHostController ) { NavHost(navController = navController, startDestination = First) { composable<First> { FirstScreen(/* ... */) // EXTRACT TO HERE } composable<Second> { SecondScreen(/* ... */) } // ... } }
Se hai seguito le indicazioni per creare l'architettura dell'interfaccia utente di Compose, in particolare su come devono essere trasmessi i
ViewModel
e gli eventi di navigazione ai composabili, il passaggio successivo consiste nel modificare il modo in cui fornisci ilViewModel
a ogni composable della schermata. Spesso puoi utilizzare l'iniezione Hilt e il relativo punto di integrazione con Compose e Navigation tramitehiltViewModel
:@Composable fun FirstScreen( // viewModel: FirstViewModel = viewModel(), viewModel: FirstViewModel = hiltViewModel(), onButtonClick: () -> Unit = {}, ) { // ... }
Sostituisci tutte le chiamate di navigazione
findNavController()
con quellenavController
e passale come eventi di navigazione a ogni schermata componibile, anziché trasmettere l'intera chiamatanavController
. Questo approccio segue le best practice per l'esposizione di eventi da funzioni componibili ai chiamanti e mantienenavController
come unica fonte attendibile.I dati possono essere passati a una destinazione creando un'istanza della classe route definita per quella destinazione. Può quindi essere ottenuto direttamente dalla voce back stack nella destinazione o da un
ViewModel
utilizzandoSavedStateHandle.toRoute()
.@Composable fun SampleNavHost( navController: NavHostController ) { NavHost(navController = navController, startDestination = First) { composable<First> { FirstScreen( onButtonClick = { // findNavController().navigate(firstScreenToSecondScreenAction) navController.navigate(Second(id = "ABC")) } ) } composable<Second> { backStackEntry -> val secondRoute = backStackEntry.toRoute<Second>() SecondScreen( id = secondRoute.id, onIconClick = { // findNavController().navigate(secondScreenToThirdScreenAction) navController.navigate(Third) } ) } // ... } }
Rimuovi tutti i frammenti, i layout XML pertinenti, la navigazione non necessaria e altre risorse e le dipendenze Fragment e Jetpack Navigation inattivi.
Puoi trovare gli stessi passaggi con ulteriori dettagli relativi a Componi navigazione nella documentazione di configurazione.
Casi d'uso comuni
Indipendentemente dal componente di navigazione utilizzato, vengono applicati gli stessi principi di navigazione.
I casi d'uso comuni durante la migrazione includono:
- Andare a un composable
- Navigare con gli argomenti
- Link diretti
- Navigazione nidificata
- Integrazione con la barra di navigazione in basso
- Integrazione con un componente di navigazione personalizzato
Per informazioni più dettagliate su questi casi d'uso, vedi Navigare con Compose.
Recupera dati complessi durante la navigazione
Ti consigliamo vivamente di non passare oggetti di dati complessi durante la navigazione. Trasmetti invece le informazioni minime necessarie, come un identificatore univoco o un'altra forma di ID, come argomenti quando esegui azioni di navigazione. Dovresti archiviare oggetti complessi come dati in un'unica fonte attendibile, come il livello dati. Per ulteriori informazioni, vedi Recupero di dati complessi durante la navigazione.
Se i tuoi frammenti passano oggetti complessi come argomenti, ti consigliamo di eseguire prima il refactoring del codice in modo da poter memorizzare e recuperare questi oggetti dal livello dati. Consulta il repository Ora su Android per alcuni esempi.
Limitazioni
Questa sezione descrive le limitazioni attuali di Compose Navigazione.
Migrazione incrementale a Navigation Compose
Al momento, non puoi utilizzare Navigation Compose continuando a utilizzare i frammenti come destinazioni nel codice. Per iniziare a utilizzare Navigation Compose, tutte le tue destinazioni devono essere componibili. Puoi monitorare questa richiesta di funzionalità nell'Issue Tracker.
Animazioni di transizione
A partire da Navigazione 2.7.0-alpha01, il supporto per l'impostazione di transizioni
personalizzate, in precedenza a partire da AnimatedNavHost
, è ora
supportato direttamente in NavHost
. Per ulteriori informazioni, leggi le note di rilascio.
Scopri di più
Per ulteriori informazioni sulla migrazione a Navigation Compose, consulta le seguenti risorse:
- Codelab Navigation Compose: apprendi le nozioni di base di Navigation Compose con un codelab pratico.
- Ora nel repository Android: un'app Android completamente funzionale realizzata interamente con Kotlin e Jetpack Compose, che segue le best practice di progettazione e sviluppo di Android e include Navigation Compose.
- Migrazione di Sunflower a Jetpack Compose: un post del blog che documenta il percorso di migrazione dell'app di esempio Sunflower da Views a Compose, che include anche la migrazione a Navigation Compose.
- Jetnews per ogni schermata: un post del blog che documenta il refactoring e la migrazione dell'esempio Jetnews per supportare tutte le schermate con Jetpack Compose e Navigation Compose.
Consigliati per te
- Nota: il testo del link viene visualizzato quando JavaScript è disattivato
- Navigare con Compose
- Compose e altre librerie
- Altre considerazioni