Auf dieser Seite finden Sie eine Anleitung zur Modularisierung Ihres Navigationscodes. Sie soll die allgemeinen Hinweise zur App-Modularisierung ergänzen.
Übersicht
Beim Modularisieren des Navigationscodes werden zusammengehörige Navigationsschlüssel und die zugehörigen Inhalte in separate Module aufgeteilt. So lassen sich die Verantwortlichkeiten klar trennen und Sie können in Ihrer App zwischen verschiedenen Funktionen wechseln.
So modularisieren Sie Ihren Navigationscode:
- Erstellen Sie zwei Untermodule:
apiundimplfür jede Funktion in Ihrer App. - Platzieren Sie die Navigationsschlüssel für jede Funktion im zugehörigen
api-Modul. - Platzieren Sie
entryProvidersund navigierbare Inhalte für jede Funktion im zugehörigenimpl-Modul. - Stellen Sie
entryProvidersfür Ihre Haupt-App-Module bereit, entweder direkt oder über die Abhängigkeitsinjektion.
Funktionen in API- und Implementierungsuntermodule aufteilen
Erstellen Sie für jede Funktion in Ihrer App zwei Untermodule mit den Namen api und impl (kurz für „Implementierung“). Anhand der folgenden Tabelle können Sie entscheiden, wo Sie den Navigationscode platzieren.
Modulname |
Enthält |
|
|
|
Inhalte für diese Funktion, einschließlich Definitionen für |
Bei diesem Ansatz kann eine Funktion zur anderen navigieren, indem die Inhalte des zugehörigen impl-Moduls von den Navigationsschlüsseln eines anderen Moduls abhängen, das im api-Modul enthalten ist.
Navigationseinträge mit Erweiterungsfunktionen trennen
In Navigation 3 wird navigierbarer Inhalt über Navigationseinträge definiert. Wenn Sie diese Einträge in separate Module aufteilen möchten, erstellen Sie Erweiterungsfunktionen für EntryProviderScope und verschieben Sie sie in das impl-Modul für diese Funktion.
Diese werden als Eintragsgeneratoren bezeichnet.
Das folgende Codebeispiel zeigt einen Eintrags-Builder, mit dem zwei Navigationseinträge erstellt werden.
// 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 } } }
Rufen Sie diese Funktion mit der entryProvider-DSL auf, wenn Sie entryProvider in Ihrem Haupt-App-Modul definieren.
// import androidx.navigation3.runtime.entryProvider // import androidx.navigation3.ui.NavDisplay NavDisplay( entryProvider = entryProvider { featureAEntryBuilder() }, // ... )
Einträge mithilfe der Abhängigkeitsinjektion zur Haupt-App hinzufügen
Im vorherigen Codebeispiel wird jeder Eintrags-Builder direkt von der Haupt-App über die entryProvider-DSL aufgerufen. Wenn Ihre App viele Bildschirme oder Funktionsmodule hat, ist das möglicherweise nicht gut skalierbar.
Um dieses Problem zu beheben, muss jedes Featuremodul seine Eintrags-Builder mithilfe der Abhängigkeitsinjektion in die Aktivität der App einbringen.
Im folgenden Code werden beispielsweise Dagger-Multibindings, insbesondere @IntoSet, verwendet, um die Eintrags-Builder in ein Set einzufügen, das zu MainActivity gehört. Diese werden dann iterativ in entryProvider aufgerufen, sodass nicht mehr zahlreiche Entry Builder-Funktionen explizit aufgerufen werden müssen.
Funktionsmodul
// 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() } }
App-Modul
// 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() } }, // ... ) } } }
Wenn Ihre Navigationseinträge navigieren müssen, z. B. wenn sie UI-Elemente enthalten, die zu neuen Bildschirmen führen, fügen Sie jeder Builder-Funktion ein Objekt hinzu, das den Navigationsstatus der App ändern kann.
Ressourcen
Codebeispiele für die Modularisierung von Navigation 3-Code finden Sie hier: