Zaprojektuj wykres nawigacyjny

Komponent Nawigacja używa wykresu nawigacyjnego do zarządzania nawigacji. Wykres nawigacyjny to struktura danych, która zawiera: miejsce docelowe w aplikacji i połączenia między nimi.

Typy miejsc docelowych

Istnieją 3 ogólne typy miejsc docelowych: hostowane, okna dialogowe i aktywność. w poniższej tabeli podano te 3 typy miejsc docelowych i ich zastosowania.

Typ

Opis

Przykłady zastosowań

Hostowane

Wypełnia cały host nawigacji. Oznacza to, że rozmiar hostowanego miejsca docelowego jest taki sam jak rozmiar hosta nawigacji, a poprzednie miejsca docelowe nie są widoczne.

Ekran główny i ekran szczegółów.

Dialog

Widoczne są komponenty interfejsu nakładki. Nie jest on powiązany z lokalizacją hosta nawigacji ani jego rozmiarem. Poprzednie miejsca docelowe są widoczne poniżej miejsca docelowego.

Alerty, wybory, formularze.

Aktywność

Reprezentuje unikalne ekrany lub funkcje aplikacji.

Pełni funkcję punktu wyjścia z wykresu nawigacyjnego, który rozpoczyna nową aktywność na Androidzie zarządzanym niezależnie od komponentu Nawigacja.

We współczesnych programach na Androida aplikacja składa się z jednego działania. Dlatego miejsc docelowych aktywności najlepiej jest używać podczas interakcji z działaniami zewnętrznymi lub w ramach procesu migracji.

Ten dokument zawiera przykłady hostowanych miejsc docelowych, które są najczęściej najpopularniejsze i podstawowe miejsca docelowe. Informacje na ten temat znajdziesz w przewodnikach inne miejsca docelowe:

Platformy

Choć w każdym przypadku obowiązuje ten sam ogólny przepływ pracy, to sposób tworzenia host nawigacji i wykres zależą od używanej platformy interfejsu użytkownika.

  • Utwórz: użyj funkcji kompozycyjnej NavHost. Dodaj do niego element NavGraph za pomocą Kotlin DSL: Wykres można utworzyć na dwa sposoby:
    • W ramach NavHost: zbuduj wykres nawigacyjny bezpośrednio jako dodania NavHost.
    • Automatyzacja: użyj metody NavController.createGraph(). aby utworzyć NavGraph i przekazać go bezpośrednio do NavHost.
  • Fragmenty: jeśli używasz fragmentów w strukturze interfejsu widoków, użyj parametru NavHostFragment jako gospodarza. Istnieje kilka sposobów na utworzenie nawigacji wykres:
    • Programowo: użyj DSL Kotlin, aby utworzyć NavGraph i zastosować ją bezpośrednio w usłudze NavHostFragment.
      • Funkcja createGraph() używana z DSL Kotlin w przypadku fragmentami i funkcja tworzenia wiadomości działa tak samo.
    • XML: wpisz host nawigacji i wykres bezpośrednio w pliku XML.
    • Edytor Android Studio: użyj edytora GUI w Android Studio, aby utworzyć i dostosować wykres jako plik zasobów XML.
.

Compose

W narzędziu Compose zdefiniuj trasę za pomocą zserializowanego obiektu lub klasy. Trasa A opisuje, jak dotrzeć do celu, i zawiera wszystkie informacje podane przez wymaga miejsca docelowego. Po zdefiniowaniu tras użyj funkcji NavHost kompozycyjne do utworzenia grafu nawigacyjnego. Przyjrzyjmy się temu przykładowi:

@Serializable
object Profile
@Serializable
object FriendsList

val navController = rememberNavController()

NavHost(navController = navController, startDestination = Profile) {
    composable<Profile> { ProfileScreen( /* ... */ ) }
    composable<FriendsList> { FriendsListScreen( /* ... */ ) }
    // Add more destinations similarly.
}
  1. Zserialowalny obiekt reprezentuje każdą z dwóch tras: Profile i FriendsList
  2. Wywołanie funkcji NavHost kompozycyjnej przekazuje NavController i trasę dla miejsca docelowego.
  3. Funkcja lambda przekazana do funkcji NavHost ostatecznie wywołuje funkcję NavController.createGraph() i zwraca NavGraph.
  4. Każda trasa jest dostarczana jako argument typu dla NavGraphBuilder.composable<T>(), który dodaje miejsce docelowe do w wyniku NavGraph.
  5. W tym celu funkcja lambda przekazana do funkcji composableNavHost miejsce docelowe.
.

Omówienie funkcji lambda

Aby lepiej zrozumieć, do czego służy lambda, która tworzy element NavGraph, weź pod uwagę te kwestie: taki sam wykres jak w poprzednim fragmencie, możesz utworzyć NavGraph oddzielnie za pomocą pola NavController.createGraph() i przekaż je do: bezpośrednio NavHost:

val navGraph by remember(navController) {
  navController.createGraph(startDestination = Profile)) {
    composable<Profile> { ProfileScreen( /* ... */ ) }
    composable<FriendsList> { FriendsListScreen( /* ... */ ) }
  }
}
NavHost(navController, navGraph)

Przekazywanie argumentów

Jeśli musisz przekazać dane do miejsca docelowego, zdefiniuj trasę za pomocą klasy, która ma parametry. Na przykład trasa Profile jest klasą danych z atrybutem name .

@Serializable
data class Profile(val name: String)

Za każdym razem, gdy musisz przekazać argumenty do tego miejsca docelowego, tworzysz instancję klasy trasy, przekazując argumenty do konstruktora klas.

Dla argumentów opcjonalnych utwórz pola dopuszczające wartości null z wartością domyślną.

@Serializable
data class Profile(val nickname: String? = null)

Uzyskiwanie instancji trasy

Wystąpienie trasy można uzyskać za pomocą funkcji NavBackStackEntry.toRoute() lub SavedStateHandle.toRoute() Gdy tworzysz miejsce docelowe za pomocą composable(), jako parametr dostępny jest NavBackStackEntry.

@Serializable
data class Profile(val name: String)

val navController = rememberNavController()

NavHost(navController = navController, startDestination = Profile(name="John Smith")) {
    composable<Profile> { backStackEntry ->
        val profile: Profile = backStackEntry.toRoute()
        ProfileScreen(name = profile.name) }
}

Uwaga:

  • Trasa Profile określa punkt początkowy nawigacji wykres z "John Smith" jako argumentem funkcji name.
  • Samo miejsce docelowe to blok composable<Profile>{}.
  • Funkcja kompozycyjna ProfileScreen przyjmuje własną wartość parametru profile.name name argument.
  • W związku z tym wartość "John Smith" przekazuje się do ProfileScreen.

Przykład z minimalną ilością danych

Kompletny przykład współdziałania elementów NavController i NavHost:

@Serializable
data class Profile(val name: String)

@Serializable
object FriendsList

// Define the ProfileScreen composable.
@Composable
fun ProfileScreen(
    profile: Profile
    onNavigateToFriendsList: () -> Unit,
  ) {
  Text("Profile for ${profile.name}")
  Button(onClick = { onNavigateToFriendsList() }) {
    Text("Go to Friends List")
  }
}

// Define the FriendsListScreen composable.
@Composable
fun FriendsListScreen(onNavigateToProfile: () -> Unit) {
  Text("Friends List")
  Button(onClick = { onNavigateToProfile() }) {
    Text("Go to Profile")
  }
}

// Define the MyApp composable, including the `NavController` and `NavHost`.
@Composable
fun MyApp() {
  val navController = rememberNavController()
  NavHost(navController, startDestination = Profile(name = "John Smith")) {
    composable<Profile> { backStackEntry ->
        val profile: Profile = backStackEntry.toRoute()
        ProfileScreen(
            profile = profile,
            onNavigateToFriendsList = {
                navController.navigate(route = FriendsList)
            }
        )
    }
    composable<FriendsList> {
      FriendsListScreen(
        onNavigateToProfile = {
          navController.navigate(
            route = Profile(name = "Aisha Devi")
          )
        }
      )
    }
  }
}

Jak widać we fragmencie kodu, zamiast przekazywać NavController do komponentu za pomocą funkcji kompozycyjnych, ujawnianie zdarzenia obiektowi NavHost. Oznacza to, że elementy kompozycyjne powinny ma parametr typu () -> Unit, dla którego funkcja NavHost przekazuje wartość lambda który dzwoni pod numer NavController.navigate().

Fragmenty

Jak pisaliśmy w poprzednich sekcjach, podczas używania fragmentów dostępna jest opcja do programowego tworzenia grafu nawigacyjnego w języku Kotlin DSL, XML Edytor Android Studio.

Szczegółowe informacje na ten temat znajdziesz w sekcjach poniżej.

Automatyzacja

Za pomocą lustrzanek DSL Kotlin można w sposób zautomatyzowany tworzyć wykresy nawigacyjne fragmenty. Jest to pod wieloma względami bardziej uporządkowane i nowoczesne niż użycie języka XML. .

Przyjrzyjmy się przykładowi, w którym zastosowano wykres nawigacji na 2 ekrany.

Najpierw musisz utworzyć obiekt NavHostFragment, który nie może zawierać: element app:navGraph:

<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <androidx.fragment.app.FragmentContainerView
        android:id="@+id/nav_host_fragment"
        android:name="androidx.navigation.fragment.NavHostFragment"
        android:layout_width="match_parent"
        android:layout_height="match_parent" />
</FrameLayout>

Następnie przekaż id z NavHostFragment do NavController.findNavController. Powiąże to element NavController z NavHostFragment.

Następnie wywołanie NavController.createGraph() łączy wykres z NavController, a w związku z tym również NavHostFragment:

@Serializable
data class Profile(val name: String)

@Serializable
object FriendsList

// Retrieve the NavController.
val navController = findNavController(R.id.nav_host_fragment)

// Add the graph to the NavController with `createGraph()`.
navController.graph = navController.createGraph(
    startDestination = Profile(name = "John Smith")
) {
    // Associate each destination with one of the route constants.
    fragment<ProfileFragment, Profile> {
        label = "Profile"
    }

    fragment<FriendsListFragment, FriendsList>() {
        label = "Friends List"
    }

    // Add other fragment destinations similarly.
}

Ten sposób korzystania z DSL jest bardzo podobny do przepływu pracy opisanego w poprzedniej sekcji dotyczącej tworzenia. Na przykład zarówno tam, jak i tutaj Funkcja NavController.createGraph() generuje NavGraph. Podobnie, chociaż NavGraphBuilder.composable() dodaje do wykresu miejsca docelowe kompozycyjne NavGraphBuilder.fragment() dodaje miejsce docelowe fragmentu.

Więcej informacji o korzystaniu z lustrzanki cyfrowej Kotlin znajdziesz w artykule Tworzenie wykresu za pomocą NavGraphBuilder DSL.

XML

Kod XML możesz wpisać bezpośrednio samodzielnie. Poniższy przykład odzwierciedla i jest odpowiednik przykładu z trybem 2 ekranów z poprzedniej sekcji.

Najpierw utwórz NavHostFragment. Służy on jako host nawigacji, zawiera rzeczywisty wykres nawigacyjny.

Minimalna implementacja elementu NavHostFragment:

<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <androidx.fragment.app.FragmentContainerView
        android:id="@+id/nav_host_fragment"
        android:name="androidx.navigation.fragment.NavHostFragment"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        app:navGraph="@navigation/nav_graph" />

</FrameLayout>

NavHostFragment zawiera atrybut app:navGraph. Użyj tego atrybutu aby połączyć wykres nawigacji z hostem nawigacji. Oto przykład zastosowania wykresu:

<navigation xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:id="@+id/nav_graph"
    app:startDestination="@id/profile">

    <fragment
        android:id="@+id/profile"
        android:name="com.example.ProfileFragment"
        android:label="Profile">

        <!-- Action to navigate from Profile to Friends List. -->
        <action
            android:id="@+id/action_profile_to_friendslist"
            app:destination="@id/friendslist" />
    </fragment>

    <fragment
        android:id="@+id/friendslist"
        android:name="com.example.FriendsListFragment"
        android:label="Friends List" />

    <!-- Add other fragment destinations similarly. -->
</navigation>

Działają one do definiowania połączeń między różnymi miejscami docelowymi. W w tym przykładzie fragment profile zawiera działanie, które przekierowuje do strony friendslist Więcej informacji znajdziesz w sekcji Korzystanie z działań nawigacyjnych Fragmenty kodu.

Edytor

Wykresem nawigacyjnym możesz zarządzać w Edytorze nawigacji w tej sekcji: Android Studio. Jest to właściwie GUI, który służy do tworzenia i edytowania NavigationFragment XML, tak jak w poprzedniej sekcji.

Więcej informacji znajdziesz w sekcji Edytor nawigacji.

Wykresy zagnieżdżone

Możesz też używać wykresów zagnieżdżonych. Wiąże się to z wykorzystaniem wykresu jako nawigacji miejsce docelowe. Więcej informacji znajdziesz w artykule Wykresy zagnieżdżone.

Dalsza lektura

Więcej podstawowych pojęć związanych z nawigacją znajdziesz w tych przewodnikach:

  • Omówienie: zapoznaj się z ogólnym omówieniem Nawigacji. .
  • Miejsca docelowe aktywności: przykłady implementacji miejsc docelowych. które kierują użytkownika do działań.
  • Konta docelowe w oknach: przykłady tworzenia miejsc docelowych, które kierować użytkownika do okna dialogowego.
  • Nawigowanie do celu: szczegółowy przewodnik z informacjami o tym, przejść z jednego miejsca docelowego do drugiego.
  • Wykresy zagnieżdżone: szczegółowy przewodnik po zagnieżdżaniu jednego elementu nawigacyjnego. wykres w obrębie innego wykresu.