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.

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.