Na tej stronie znajdziesz wskazówki dotyczące modularyzacji kodu nawigacji. Ma ona uzupełniać ogólne wskazówki dotyczące modularizacji aplikacji.
Omówienie
Modularyzacja kodu nawigacji to proces dzielenia powiązanych kluczy nawigacji i reprezentowanych przez nie treści na osobne moduły. Zapewnia to wyraźne rozdzielenie zakresów odpowiedzialności i umożliwia poruszanie się między różnymi funkcjami aplikacji.
Aby podzielić kod nawigacji na moduły:
- Utwórz 2 podmoduły:
apiiimpldla każdej funkcji w aplikacji. - Umieść klucze nawigacyjne dla każdej funkcji w jej module
api. - Umieść
entryProvidersi treści, po których można nawigować, dla każdej funkcji w odpowiednim moduleimpl. - Przekaż
entryProvidersdo głównych modułów aplikacji bezpośrednio lub za pomocą wstrzykiwania zależności.
Podzielenie funkcji na podmoduły API i implementacji
Dla każdej funkcji w aplikacji utwórz 2 podmoduły o nazwach api i impl (skrót od „implementation”). Z tabeli poniżej dowiesz się, gdzie umieścić kod nawigacji.
Nazwa modułu |
Zawiera |
|
|
|
Treści tej funkcji, w tym definicje |
Dzięki temu jedna funkcja może przechodzić do innej, ponieważ jej treść, zawarta w module impl, zależy od klawiszy nawigacyjnych innego modułu, zawartych w module api tego modułu.
Oddzielanie wpisów nawigacyjnych za pomocą funkcji rozszerzeń
W Navigation 3 treści, po których można się poruszać, są definiowane za pomocą wpisów nawigacyjnych. Aby rozdzielić te wpisy na osobne moduły, utwórz funkcje rozszerzające w EntryProviderScope i przenieś je do modułu impl dla tej funkcji.
Są one nazywane kreatorami wpisów.
Poniższy przykład kodu pokazuje konstruktora wpisów, który tworzy 2 wpisy nawigacyjne.
// 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 } } }
Wywołaj tę funkcję za pomocą entryProvider DSL podczas definiowania entryProvider w głównym module aplikacji.
// import androidx.navigation3.runtime.entryProvider // import androidx.navigation3.ui.NavDisplay NavDisplay( entryProvider = entryProvider { featureAEntryBuilder() }, // ... )
Używanie wstrzykiwania zależności do dodawania wpisów do głównej aplikacji
W poprzednim przykładzie kodu każdy konstruktor wpisów jest wywoływany bezpośrednio przez główną aplikację za pomocą języka DSL entryProvider. Jeśli aplikacja ma wiele ekranów lub modułów funkcji, może to nie być skalowalne.
Aby to rozwiązać, spraw, aby każdy moduł funkcji przekazywał swoje konstruktory wpisów do aktywności aplikacji za pomocą wstrzykiwania zależności.
Na przykład ten kod używa wielokrotnych powiązań Daggera, a konkretnie @IntoSet, do wstrzykiwania konstruktorów wpisów do Set należącego do MainActivity. Są one następnie wywoływane iteracyjnie w funkcji entryProvider, co eliminuje konieczność jawnego wywoływania wielu funkcji tworzenia wpisów.
Moduł funkcji
// 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() } }
Moduł aplikacji
// 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() } }, // ... ) } } }
Jeśli wpisy nawigacyjne wymagają nawigacji (np. zawierają elementy interfejsu, które prowadzą do nowych ekranów), wstrzyknij do każdej funkcji konstruktora obiekt, który może modyfikować stan nawigacji aplikacji.
Materiały
Przykłady kodu pokazujące, jak podzielić kod Navigation 3 na moduły, znajdziesz w tych artykułach:
- Przepisy na kod architektury Navigation 3
- Ścieżka edukacyjna dotycząca modularyzacji w aplikacji Now in Android
- Androidify