L'API Navigation Compose ti consente di navigare tra i componibili in un'app Compose, sfruttando al contempo il componente, l'infrastruttura e le funzionalità di Jetpack Navigation's.
Questa pagina descrive come eseguire la migrazione da Jetpack Navigation basato su Fragment a Navigation Compose, nell'ambito della migrazione più ampia dell'UI basata su View a Jetpack Compose.
Prerequisiti per la migrazione
Puoi eseguire la migrazione a Navigation Compose una volta che sei in grado di sostituire tutti i Fragment con i relativi componibili dello schermo. I componibili dello schermo possono contenere un mix di contenuti Compose e View, ma tutte le destinazioni di navigazione devono essere componibili per consentire la migrazione di Navigation Compose. Fino ad allora, devi continuare a utilizzare il componente di navigazione basato su Fragment nel codebase di interoperabilità View e Compose. Per ulteriori informazioni, consulta la documentazione sull'interoperabilità della navigazione per maggiori informazioni.
Passaggi della migrazione
Indipendentemente dal fatto che tu stia seguendo la nostra strategia di migrazione consigliata o che tu stia adottando un altro approccio, arriverai a un punto in cui tutte le destinazioni di navigazione sono componibili dello schermo, con i Fragment che fungono solo da container componibili. A questo punto, 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 refactoring importanti di altri livelli dell'app, a parte il livello dell'UI.
Per eseguire la migrazione a Navigation Compose:
- Aggiungi la dipendenza di Navigation Compose alla tua app.
Crea un componibile
App-levele aggiungilo alla tuaActivitycome punto di ingresso di Compose, sostituendo la configurazione del layout View: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 objectper le destinazioni che non richiedono dati edata classoclassper le destinazioni che richiedono dati.@Serializable data object First @Serializable data class Second(val id: String) @Serializable data object Third
Configura
NavControllerin un punto in cui tutti i componibili che devono farvi riferimento abbiano accesso (di solito all'interno del tuoAppcomponibile). Questo approccio segue i principi di innalzamento dello stato e ti consente di utilizzareNavControllercome fonte attendibile per navigare tra le schermate componibili e mantenere il back stack:@Composable fun SampleApp() { val navController = rememberNavController() // ... }
Crea
NavHostdella tua app all'interno del componibileAppe passanavController:@Composable fun SampleApp() { val navController = rememberNavController() SampleNavHost(navController = navController) } @Composable fun SampleNavHost( navController: NavHostController ) { NavHost(navController = navController, startDestination = First) { // ... } }
Aggiungi le destinazioni
composableper creare il grafico di navigazione. Se ogni schermata è stata migrata in precedenza a Compose, questo passaggio consiste solo nell'estrarre questi componibili dello schermo dai Fragment nelle destinazionicomposable: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 su come strutturare l'interfaccia utente di Compose, in particolare su come
ViewModele gli eventi di navigazione devono essere passati ai componibili, il passaggio successivo consiste nel modificare il modo in cui fornisciViewModela ogni componibile dello schermo. 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 quellenavControllere passale come eventi di navigazione a ogni schermata componibile, anziché passare l'interonavController. Questo approccio segue le best practices per esporre gli eventi dalle funzioni componibili ai chiamanti e mantienenavControllercome unica fonte attendibile.I dati possono essere passati a una destinazione creando un'istanza della classe di route definita per quella destinazione. Può essere ottenuto direttamente dalla voce dello stack indietro nella destinazione o da un
ViewModelutilizzandoSavedStateHandle.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 Fragment, i layout XML pertinenti, le risorse di navigazione e di altro tipo non necessarie e le dipendenze obsolete di Fragment e Jetpack Navigation.
Puoi trovare gli stessi passaggi con maggiori dettagli relativi a Navigation Compose nella documentazione di configurazione.
Casi d'uso comuni
Indipendentemente dal componente di navigazione che utilizzi, si applicano gli stessi principi di navigazione.
I casi d'uso comuni durante la migrazione includono:
- Navigare in un componibile
- Navigare con gli argomenti
- Deep ink
- 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, consulta la pagina Navigare con Compose.
Recuperare dati complessi durante la navigazione
Ti consigliamo vivamente di non passare oggetti di dati complessi durante la navigazione. Passa invece le informazioni minime necessarie, ad esempio un identificatore univoco o un'altra forma di ID, come argomenti quando esegui azioni di navigazione. Devi archiviare gli oggetti complessi come dati in un'unica fonte attendibile, ad esempio il livello dati. Per ulteriori informazioni, consulta la pagina Recuperare dati complessi durante la navigazione.
Se i Fragment passano oggetti complessi come argomenti, valuta la possibilità di eseguire prima il refactoring del codice in modo da consentire l'archiviazione e il recupero di questi oggetti dal livello dati. Per esempi, consulta il repository Now in Android per.
Limitazioni
Questa sezione descrive le limitazioni attuali di Navigation Compose.
Migrazione incrementale a Navigation Compose
Al momento, non puoi utilizzare Navigation Compose mentre utilizzi ancora i Fragment come destinazioni nel codice. Per iniziare a utilizzare Navigation Compose, tutte le destinazioni devono essere componibili. Puoi monitorare questa richiesta di funzionalità nel Issue Tracker.
Animazioni di transizione
A partire da Navigation 2.7.0-alpha01, il supporto per l'impostazione di transizioni personalizzate, in precedenza da AnimatedNavHost, è ora supportato direttamente in NavHost. Per ulteriori informazioni, consulta le note di rilascio.
Scopri di più
Per ulteriori informazioni sulla migrazione a Navigation Compose, consulta le seguenti risorse:
- Codelab di Navigation Compose: scopri le nozioni di base di Navigation Compose con un codelab pratico.
- Repository Now in Android: un'app per Android completamente funzionale creata 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 View a Compose, che include anche la migrazione a Navigation Compose.
- Jetnews per ogni schermo: un post del blog che documenta il refactoring e la migrazione dell'esempio Jetnews per supportare tutti gli schermi 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