Questa pagina è una guida per la modularizzazione del codice di navigazione. È inteso a integrare le indicazioni generali per la modularizzazione delle app.
Panoramica
La modularizzazione del codice di navigazione è il processo di separazione dei tasti di navigazione correlati e dei contenuti che rappresentano in moduli singoli. In questo modo, le responsabilità sono chiaramente separate e puoi navigare tra le diverse funzionalità dell'app.
Per modularizzare il codice di navigazione:
- Crea due sottomoduli:
apieimplper ogni funzionalità della tua app - Inserisci i tasti di navigazione per ogni funzionalità nel relativo modulo
api - Inserisci
entryProviderse contenuti navigabili per ogni funzionalità nel moduloimplassociato. - Fornisci
entryProvidersai moduli principali dell'app, direttamente o utilizzando l'inserimento delle dipendenze
Suddividere le funzionalità in moduli secondari di API e implementazione
Per ogni funzionalità della tua app, crea due sottomoduli denominati api e impl
(abbreviazione di "implementazione"). Utilizza la tabella seguente per decidere dove inserire
il codice di navigazione.
Nome modulo |
Contiene |
|
|
|
Contenuti per questa funzionalità, incluse le definizioni di
|
Questo approccio consente a una funzionalità di passare a un'altra consentendo ai suoi contenuti, contenuti nel modulo impl, di dipendere dai tasti di navigazione di un altro modulo, contenuto nel modulo api.
Separare le voci di navigazione utilizzando le funzioni di estensione
In Navigazione 3, i contenuti navigabili vengono definiti utilizzando le voci di navigazione. Per
separare queste voci in moduli distinti, crea funzioni di estensione su
EntryProviderScope e spostale nel modulo impl per quella funzionalità.
Questi sono noti come generatori di voci.
Il seguente esempio di codice mostra un generatore di voci che crea due voci di navigazione.
// import androidx.navigation3.runtime.EntryProviderScope // import androidx.navigation3.runtime.NavKey fun EntryProviderScope<NavKey>.featureAEntryBuilder() { entry<KeyA> { ContentRed("Screen A") { // Content for screen A } } entry<KeyA2> { ContentGreen("Screen A2") { // Content for screen A2 } } }
Chiama questa funzione utilizzando il DSL entryProvider quando definisci
entryProvider nel modulo principale dell'app.
// import androidx.navigation3.runtime.entryProvider // import androidx.navigation3.ui.NavDisplay NavDisplay( entryProvider = entryProvider { featureAEntryBuilder() }, // ... )
Utilizzare l'inserimento delle dipendenze per aggiungere voci all'app principale
Nell'esempio di codice precedente, ogni generatore di voci viene chiamato direttamente dall'app principale
utilizzando il linguaggio specifico del dominio entryProvider. Se la tua app ha molte schermate o moduli di funzionalità, questo potrebbe non essere scalabile.
Per risolvere il problema, fai in modo che ogni modulo delle funzionalità contribuisca con i propri builder di voci all'attività dell'app utilizzando l'inserimento delle dipendenze.
Ad esempio, il seguente codice utilizza Dagger multibindings,
in particolare @IntoSet, per inserire i builder di voci in un Set di proprietà di
MainActivity. Questi vengono poi chiamati in modo iterativo all'interno di entryProvider,
eliminando la necessità di chiamare esplicitamente numerose funzioni di creazione delle voci.
Modulo delle funzionalità
// import dagger.Module // import dagger.Provides // import dagger.hilt.InstallIn // import dagger.hilt.android.components.ActivityRetainedComponent // import dagger.multibindings.IntoSet @Module @InstallIn(ActivityRetainedComponent::class) object FeatureAModule { @IntoSet @Provides fun provideFeatureAEntryBuilder() : EntryProviderScope<NavKey>.() -> Unit = { featureAEntryBuilder() } }
Modulo app
// import android.os.Bundle // import androidx.activity.ComponentActivity // import androidx.activity.compose.setContent // import androidx.navigation3.runtime.EntryProviderScope // import androidx.navigation3.runtime.NavKey // import androidx.navigation3.runtime.entryProvider // import androidx.navigation3.ui.NavDisplay // import javax.inject.Inject class MainActivity : ComponentActivity() { @Inject lateinit var entryBuilders: Set<@JvmSuppressWildcards EntryProviderScope<NavKey>.() -> Unit> override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContent { NavDisplay( entryProvider = entryProvider { entryBuilders.forEach { builder -> this.builder() } }, // ... ) } } }
Se le voci di navigazione devono navigare, ad esempio contengono elementi dell'interfaccia utente che rimandano a nuove schermate, inserisci un oggetto in grado di modificare lo stato di navigazione dell'app in ogni funzione del builder.
Risorse
Per esempi di codice che mostrano come modularizzare il codice di Navigation 3, vedi:
- Ricette di codice dell'architettura di Navigation 3
- Il percorso di apprendimento sulla modularizzazione dall'app Now in Android
- Androidify