Sprawdzone metody nawigacji w projektach opartych na wielu modułach

Wykres nawigacyjny może się składać z dowolnej kombinacji tych elementów:

  • Pojedyncze miejsce docelowe, np. <fragment>.
  • Wykres zagnieżdżony który obejmuje zestaw powiązanych miejsc docelowych.
  • element <include>, który pozwala umieścić kolejny plik wykresu nawigacyjnego, tak jakby był zagnieżdżonych.

Ta elastyczność umożliwia łączenie mniejszych wykresów nawigacyjnych w celu do pełnego wykresu nawigacji w aplikacji, nawet jeśli te mniejsze wykresy są dostarczane w osobnych modułach.

W przykładach w tym temacie każda z tych wartości moduł funkcji dotyczy wokół jednej cechy udostępnia jeden wykres nawigacyjny obejmujący wszystkie miejsca docelowe potrzebnych do wdrożenia tej funkcji. W produkcyjnej aplikacji możesz mieć wiele elementów modułów podrzędnych na niższym poziomie, które są szczegółami implementacji tego wyższego poziomu. z modułu funkcji. Każdy z tych modułów funkcji jest uwzględniony bezpośrednio lub pośrednio, na app. Przykład aplikacja wielomodułowa użyta w tym dokumencie ma następującą strukturę:

graf zależności dla przykładowej aplikacji składającej się z wielu modułów
. miejsce docelowe przykładowej aplikacji
.
Rys. 1. Architektura aplikacji i początkowe miejsce docelowe w przypadku przykładowej aplikacji.
.

Każdy moduł funkcji jest autonomiczną jednostką z własnym wykresem nawigacji i miejsc docelowych. Moduł app zależy od każdego z nich, dodając je jako szczegóły implementacji w pliku build.gradle, jak poniżej:

Odlotowe

dependencies {
    ...
    implementation project(":feature:home")
    implementation project(":feature:favorites")
    implementation project(":feature:settings")

Kotlin

dependencies {
    ...
    implementation(project(":feature:home"))
    implementation(project(":feature:favorites"))
    implementation(project(":feature:settings"))

Rola modułu app

Moduł app odpowiada za przedstawienie pełnego wykresu i dodanie NavHost do interfejsu. W module app możesz odwołać się do wykresów z biblioteki, korzystając z funkcji <include> Choć użycie funkcji <include> działa tak samo jak użycie grafu zagnieżdżonego. <include> obsługuje wykresy z innych modułów projektu lub z biblioteki w projektach jak w tym przykładzie:

<?xml version="1.0" encoding="utf-8"?>
<navigation xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:id="@+id/nav_graph"
    app:startDestination="@id/home_nav_graph">

    <include app:graph="@navigation/home_navigation" />
    <include app:graph="@navigation/favorites_navigation" />
    <include app:graph="@navigation/settings_navigation" />
</navigation>

Gdy biblioteka zostanie dodana do wykresu nawigacyjnego najwyższego poziomu, możesz nawiguj do wykresów bibliotecznych w razie potrzeby. Możesz na przykład utworzyć działanie, aby przejść do wykresu ustawień z fragmentu wykresu nawigacyjnego Jak widać:

<?xml version="1.0" encoding="utf-8"?>
<navigation xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:id="@+id/nav_graph"
    app:startDestination="@id/home_nav_graph">

    <include app:graph="@navigation/home_navigation" />
    <include app:graph="@navigation/favorites_navigation" />
    <include app:graph="@navigation/settings_navigation" />

    <fragment
        android:id="@+id/random_fragment"
        android:name="com.example.android.RandomFragment"
        android:label="@string/fragment_random" >
        <!-- Launch into Settings Navigation Graph -->
        <action
            android:id="@+id/action_random_fragment_to_settings_nav_graph"
            app:destination="@id/settings_nav_graph" />
    </fragment>
</navigation>

Gdy wiele modułów cech musi odwoływać się do wspólnego zestawu miejsc docelowych, np. wykresu logowania, nie należy uwzględniać tych na wykresie nawigacyjnym każdego modułu funkcji. Zamiast tego: dodaj te wspólne miejsca docelowe do wykresu nawigacyjnego w module app. W każdym module funkcji możesz poruszać się między modułami funkcji aby dotrzeć do tych popularnych miejsc.

W poprzednim przykładzie działanie określa miejsce docelowe nawigacji z @id/settings_nav_graph. Ten identyfikator odnosi się do miejsca docelowego, które jest zdefiniowane na załączonym wykresie @navigation/settings_navigation.

Nawigacja najwyższego poziomu w module aplikacji

Komponent Nawigacja zawiera NavigationUI. Ta klasa zawiera metody statyczne, które zarządzają nawigacją na górze pasek aplikacji, panel nawigacji i dolna nawigacja. Jeśli Twoja aplikacja miejsca docelowe najwyższego poziomu składają się z elementów interfejsu dostarczonych przez funkcję moduł app to naturalne miejsce, w którym elementy nawigacyjne i elementy interfejsu. Moduł aplikacji zależy od współpracujące ze sobą moduły funkcji, wszystkie ich miejsca docelowe są dostępne z kodu zdefiniowanego w module aplikacji. Oznacza to, że możesz używać NavigationUI do wiąż miejsca docelowe z pozycjami w menu jeśli identyfikator produktu pasuje do identyfikatora miejsca docelowego.

Na ilustracji 2 przykładowy moduł app definiuje BottomNavigationView. w ramach swojej głównej działalności. Identyfikatory pozycji menu w menu są zgodne z identyfikatorami elementów nawigacyjnych. identyfikatory wykresów z biblioteki:

<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto">

    <item
        android:id="@id/home_nav_graph"
        android:icon="@drawable/ic_home"
        android:title="Home"
        app:showAsAction="ifRoom"/>

    <item
        android:id="@id/favorites_nav_graph"
        android:icon="@drawable/ic_favorite"
        android:title="Favorites"
        app:showAsAction="ifRoom"/>

    <item
        android:id="@id/settings_nav_graph"
        android:icon="@drawable/ic_settings"
        android:title="Settings"
        app:showAsAction="ifRoom" />
</menu>

Aby umożliwić usłudze NavigationUI obsługę Dolna nawigacja, wywołanie setupWithNavController() z onCreate() w ramach głównych zajęć, na przykład na przykład:

Kotlin

override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)
    setContentView(R.layout.activity_main)
    val navHostFragment =
        supportFragmentManager.findFragmentById(R.id.nav_host_fragment) as NavHostFragment
    val navController = navHostFragment.navController

    findViewById<BottomNavigationView>(R.id.bottom_nav)
            .setupWithNavController(navController)
}

Java

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    NavHostFragment navHostFragment =
            (NavHostFragment) supportFragmentManager.findFragmentById(R.id.nav_host_fragment);
    NavController navController = navHostFragment.getNavController();
    BottomNavigationView bottomNav = findViewById(R.id.bottom_nav);

    NavigationUI.setupWithNavController(bottomNav, navController);
}

Po wpisaniu tego kodu NavigationUI przekierowuje użytkownika do odpowiedniego miejsca wykres biblioteki, gdy użytkownik klika dolny element nawigacji.

Pamiętaj, że ogólnie złe praktyki dotyczące modułów aplikacji od konkretnego miejsca docelowego osadzonego w treści moduły funkcji wykres nawigacyjny. W większości przypadków aplikacja tylko na temat punktu wejścia do dowolnego umieszczonego wykresy nawigacyjne (dotyczy to również modułów funkcji). Jeśli potrzebujesz do miejsca docelowego w głębi wykresu nawigacji Twojej biblioteki, preferowanym sposobem wykonania tego zadania jest użycie precyzyjny link. Precyzyjne linki to to jedyny sposób, w jaki biblioteka może przejść do miejsca docelowego w innym za pomocą wykresu nawigacyjnego w bibliotece.

Przechodzenie między modułami funkcji

Podczas kompilacji niezależne moduły funkcji nie mogą się widzieć, więc nie możesz używać identyfikatorów do przechodzenia do miejsc docelowych w innych modułach. Zamiast tego: używać precyzyjnego linku do poruszania się bezpośrednio do miejsca docelowego powiązanego z precyzyjny link.

Kontynuując poprzedni przykład, wyobraź sobie, że musisz przechodzić od przycisku w z modułu :feature:home do miejsca docelowego w tabeli :feature:settings. . Aby to zrobić, dodaj w ustawieniach precyzyjny link do miejsca docelowego Jak widać na wykresie nawigacji:

<?xml version="1.0" encoding="utf-8"?>
<navigation xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:id="@+id/settings_nav_graph"
    app:startDestination="@id/settings_fragment_one">

    ...

    <fragment
        android:id="@+id/settings_fragment_two"
        android:name="com.example.google.login.SettingsFragmentTwo"
        android:label="@string/settings_fragment_two" >

        <deepLink
            app:uri="android-app://example.google.app/settings_fragment_two" />
    </fragment>
</navigation>

Następnie dodaj ten kod do onClickListener przycisku na stronie głównej fragment:

Kotlin

button.setOnClickListener {
    val request = NavDeepLinkRequest.Builder
        .fromUri("android-app://example.google.app/settings_fragment_two".toUri())
        .build()
    findNavController().navigate(request)
}

Java

button.setOnClickListener(new View.OnClickListener() {
    @Override
    public void onClick(View view) {
        NavDeepLinkRequest request = NavDeepLinkRequest.Builder
            .fromUri(Uri.parse("android-app://example.google.app/settings_fragment_two"))
            .build();
        NavHostFragment.findNavController(this).navigate(request);
    }
});

W przeciwieństwie do nawigacji za pomocą identyfikatorów działań lub miejsc docelowych możesz nawigować do z dowolnego identyfikatora URI na dowolnym wykresie, nawet w różnych modułach.

W przypadku nawigowania za pomocą identyfikatora URI stos wsteczny nie jest resetowany. Działanie to w przeciwieństwie do nawigacji za pomocą precyzyjnych linków, w którym tylny stos jest zastępowany podczas nawigacji.