Komponent Navigation zapewnia prosty i ogólny sposób nawigowania do miejsca docelowego. Ten interfejs obsługuje różne konteksty i platformy interfejsu. Możesz na przykład używać komponentu Navigation z Compose, widokami, fragmentami, aktywnościami, a nawet niestandardowymi platformami interfejsu.
Z tego przewodnika dowiesz się, jak używać komponentu Navigation do nawigowania do miejsca docelowego w różnych kontekstach.
Używanie NavController
Kluczowym typem używanym do przechodzenia między miejscami docelowymi jest NavController.
Więcej informacji o samej klasie
i sposobie tworzenia jej instancji znajdziesz w artykule Tworzenie kontrolera nawigacji. Z tego przewodnika dowiesz się, jak go używać.
Nawigacja
Niezależnie od tego, której platformy interfejsu używasz, do nawigowania do miejsca docelowego możesz użyć jednej funkcji: NavController.navigate().
Dostępnych jest wiele przeciążeń funkcji navigate(). Przeciążenie, którego należy użyć, odpowiada dokładnemu kontekstowi. Na przykład, gdy nawigujesz do elementu kompozycyjnego, używasz jednego przeciążenia, a gdy nawigujesz do widoku – innego.
W sekcjach poniżej opisujemy niektóre z najważniejszych przeciążeń funkcji navigate(), których możesz używać.
Nawigowanie do elementu kompozycyjnego
Aby nawigować do elementu kompozycyjnego, użyj funkcji NavController.navigate<T>.
W przypadku tego przeciążenia funkcja navigate() przyjmuje 1 argument route, dla którego przekazujesz typ. Służy on jako klucz do miejsca docelowego.
@Serializable
object FriendsList
navController.navigate(route = FriendsList)
Aby nawigować do elementu kompozycyjnego na wykresie nawigacji, najpierw zdefiniuj swój
NavGraph tak, aby każde miejsce docelowe odpowiadało typowi. W przypadku elementów kompozycyjnych robisz to za pomocą funkcji composable().
Udostępnianie zdarzeń z funkcji kompozycyjnych
Gdy funkcja typu „composable” musi przejść do nowego ekranu, nie należy przekazywać jej odniesienia do NavController, aby mogła bezpośrednio wywołać navigate().
Zgodnie z zasadami jednokierunkowego przepływu danych (UDF) element kompozycyjny
powinien zamiast tego udostępniać zdarzenie, które obsługuje NavController.
Mówiąc wprost, element kompozycyjny powinien mieć parametr typu () -> Unit.
Gdy dodajesz miejsca docelowe do NavHost za pomocą funkcji composable(), przekaż do elementu kompozycyjnego wywołanie NavController.navigate().
Przykład znajdziesz w podsekcji poniżej.
Przykład
Aby zademonstrować informacje z poprzednich sekcji, zwróć uwagę na te punkty w poniższym fragmencie kodu:
- Każde miejsce docelowe na wykresie jest tworzone za pomocą trasy, która jest obiektem lub klasą z możliwością serializacji opisującą dane wymagane przez to miejsce docelowe.
- Element kompozycyjny
MyAppNavHostzawiera instancjęNavController. - W związku z tym wywołania
navigate()powinny występować w tym miejscu, a nie w niższym elemencie kompozycyjnym, takim jakProfileScreen. ProfileScreenzawiera przycisk, który po kliknięciu przenosi użytkownika doFriendsList. Nie wywołuje on jednak samodzielnie funkcjinavigate().- Zamiast tego przycisk wywołuje funkcję, która jest udostępniana jako parametr
onNavigateToFriends. - Gdy
MyAppNavHostdodajeProfileScreendo wykresu nawigacji, w przypadkuonNavigateToFriendsprzekazuje lambdę, która wywołujenavigate(route = FriendsList). - Dzięki temu, gdy użytkownik naciśnie przycisk
ProfileScreen, zostanie prawidłowo przeniesiony doFriendsListScreen.
@Serializable
object Profile
@Serializable
object FriendsList
@Composable
fun MyAppNavHost(
modifier: Modifier = Modifier,
navController: NavHostController = rememberNavController(),
) {
NavHost(
modifier = modifier,
navController = navController,
startDestination = Profile
) {
composable<Profile> {
ProfileScreen(
onNavigateToFriends = { navController.navigate(route = FriendsList) },
/*...*/
)
}
composable<FriendsList> { FriendsListScreen(/*...*/) }
}
}
@Composable
fun ProfileScreen(
onNavigateToFriends: () -> Unit,
/*...*/
) {
/*...*/
Button(onClick = onNavigateToFriends) {
Text(text = "See friends list")
}
}
Nawigowanie za pomocą identyfikatora liczby całkowitej
Aby nawigować do miejsca docelowego za pomocą identyfikatora liczby całkowitej, wywołaj navigate(int)
przeciążenie. Przyjmuje ono identyfikator zasobu działania lub miejsca docelowego. Poniższy fragment kodu pokazuje, jak użyć tego przeciążenia do nawigowania do ViewTransactionsFragment:
Kotlin
viewTransactionsButton.setOnClickListener { view ->
view.findNavController().navigate(R.id.viewTransactionsAction)
}
Java
viewTransactionsButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
Navigation.findNavController(view).navigate(R.id.viewTransactionsAction);
}
});
Podczas nawigowania za pomocą identyfikatorów, jeśli to możliwe, używaj działań. Działania zawierają dodatkowe informacje na wykresie nawigacji, wizualnie pokazując, jak miejsca docelowe są ze sobą połączone.
Nawigowanie za pomocą NavDeepLinkRequest
Aby nawigować do miejsca docelowego z niejawnym precyzyjnym linkiem, użyj
navigate(NavDeepLinkRequest) przeciążenia. Poniższy fragment kodu zawiera implementację tej metody:
Kotlin
val request = NavDeepLinkRequest.Builder
.fromUri("android-app://androidx.navigation.app/profile".toUri())
.build()
findNavController().navigate(request)
Java
NavDeepLinkRequest request = NavDeepLinkRequest.Builder
.fromUri(Uri.parse("android-app://androidx.navigation.app/profile"))
.build()
NavHostFragment.findNavController(this).navigate(request)
W przeciwieństwie do nawigacji za pomocą identyfikatorów działań lub miejsc docelowych możesz nawigować do dowolnego precyzyjnego linku na wykresie, niezależnie od tego, czy miejsce docelowe jest widoczne. Możesz nawigować do miejsca docelowego na bieżącym grafie lub do miejsca docelowego na zupełnie innym grafie.
Działania i typy MIME
Oprócz Uri NavDeepLinkRequest obsługuje też precyzyjne linki z
działaniami i typami MIME. Aby dodać działanie do żądania, użyj
fromAction() lub setAction(). Aby dodać typ MIME do żądania,
użyj fromMimeType() lub setMimeType().
Aby NavDeepLinkRequest prawidłowo pasował do miejsca docelowego z precyzyjnym linkiem typu implicit,
identyfikator URI, działanie i typ MIME muszą pasować do NavDeepLink w
miejscu docelowym. Identyfikatory URI muszą pasować do wzorca, działania muszą być dokładnie takie same, a typy MIME muszą być powiązane. Na przykład image/jpg pasuje do image/\*.
Dodatkowe konteksty
W tym dokumencie opisujemy, jak używać funkcji NavController.navigate() w najczęstszych
przypadkach użycia. Funkcja ta ma jednak wiele przeciążeń, których możesz używać w różnych kontekstach i w połączeniu z dowolną platformą interfejsu. Więcej informacji o tych przeciążeniach znajdziesz w dokumentacji referencyjnej.
Więcej informacji
Więcej informacji znajdziesz na tych stronach:
- Tworzenie kontrolera nawigacji
- Nawigacja i stos wsteczny
- Nawigowanie z opcjami
- Bezpieczeństwo typów w Kotlin DSL i Navigation Compose