Interfejs Navigation Compose API umożliwia poruszanie się między funkcjami kompozycyjnymi w aplikacji Compose przy jednoczesnym korzystaniu z komponentu, infrastruktury i funkcji Jetpack Navigation.
Na tej stronie opisujemy, jak przeprowadzić migrację z nawigacji Jetpack opartej na fragmentach do nawigacji Compose w ramach większej migracji interfejsu opartego na widokach do Jetpack Compose.
Wymagania wstępne migracji
Możesz przejść na Navigation Compose, gdy zastąpisz wszystkie Fragmenty odpowiednimi komponentami ekranu. Kompozycje ekranu mogą zawierać mieszankę treści Compose i View, ale wszystkie miejsca docelowe nawigacji muszą być kompozycjami, aby umożliwić migrację do Navigation Compose. Do tego czasu w kodzie View i Compose w trybie interop należy nadal używać komponentu nawigacji opartej na fragmentach. Więcej informacji znajdziesz w dokumentacji dotyczącej interoperacyjności nawigacji.
Korzystanie z Navigation Compose w aplikacji opartej wyłącznie na Compose nie jest wymagane. Możesz nadal używać komponentu Nawigacja oparta na fragmentach, o ile będziesz używać fragmentów do hostowania treści, które można komponować.
Etapy migracji
Niezależnie od tego, czy korzystasz z naszej zalecanej strategii migracji, czy stosujesz inne podejście, w pewnym momencie wszystkie miejsca docelowe nawigacji będą komponentami ekranu, a fragmenty będą pełnić rolę tylko kontenerów komponentów. Na tym etapie możesz przejść na Navigation Compose.
Jeśli Twoja aplikacja korzysta już z wzorca projektowego UDF i naszego przewodnika po architekturze, migracja do Jetpack Compose i Navigation Compose nie powinna wymagać większych zmian w innych warstwach aplikacji poza warstwą interfejsu.
Aby przeprowadzić migrację do Navigation Compose, wykonaj te czynności:
- Dodaj do aplikacji zależność Navigation Compose.
Utwórz
App-level
funkcję kompozycyjną i dodaj ją doActivity
jako punkt wejścia do Compose, zastępując konfigurację układu View:class SampleActivity : ComponentActivity() { override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) // setContentView<ActivitySampleBinding>(this, R.layout.activity_sample) setContent { SampleApp(/* ... */) } } }
Utwórz typy dla każdego miejsca docelowego nawigacji. Używaj
data object
w przypadku miejsc docelowych, które nie wymagają żadnych danych, orazdata class
lubclass
w przypadku miejsc docelowych, które wymagają danych.@Serializable data object First @Serializable data class Second(val id: String) @Serializable data object Third
Skonfiguruj
NavController
w miejscu, do którego mają dostęp wszystkie funkcje kompozycyjne, które muszą się do niego odwoływać (zwykle jest to w funkcji kompozycyjnejApp
). To podejście jest zgodne z zasadami przenoszenia stanu i umożliwia używanieNavController
jako źródła informacji do poruszania się między ekranami kompozycyjnymi i utrzymywania stosu wstecznego:@Composable fun SampleApp() { val navController = rememberNavController() // ... }
Utwórz
NavHost
aplikacji w kompozycyjnymApp
i przekażnavController
:@Composable fun SampleApp() { val navController = rememberNavController() SampleNavHost(navController = navController) } @Composable fun SampleNavHost( navController: NavHostController ) { NavHost(navController = navController, startDestination = First) { // ... } }
Dodaj miejsca docelowe
composable
, aby utworzyć wykres nawigacji. Jeśli każdy ekran został wcześniej przeniesiony do Compose, ten krok polega tylko na wyodrębnieniu tych funkcji kompozycyjnych ekranu z fragmentów do miejsc docelowychcomposable
:class FirstFragment : Fragment() { override fun onCreateView( inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle? ): View { return ComposeView(requireContext()).apply { setContent { // FirstScreen(...) EXTRACT FROM HERE } } } } @Composable fun SampleNavHost( navController: NavHostController ) { NavHost(navController = navController, startDestination = First) { composable<First> { FirstScreen(/* ... */) // EXTRACT TO HERE } composable<Second> { SecondScreen(/* ... */) } // ... } }
Jeśli postępujesz zgodnie z wskazówkami dotyczącymi projektowania interfejsu Compose, a zwłaszcza sposobu przekazywania
ViewModel
i zdarzeń nawigacji do komponentów kompozycyjnych, kolejnym krokiem jest zmiana sposobu dostarczaniaViewModel
do każdego komponentu kompozycyjnego ekranu. Wstrzykiwania Hilt i jego punktu integracji z Compose i Navigation możesz często używać za pomocąhiltViewModel
:@Composable fun FirstScreen( // viewModel: FirstViewModel = viewModel(), viewModel: FirstViewModel = hiltViewModel(), onButtonClick: () -> Unit = {}, ) { // ... }
Zastąp wszystkie wywołania nawigacji
findNavController()
wywołaniaminavController
i przekaż je jako zdarzenia nawigacji do każdego ekranu z funkcją kompozycji, zamiast przekazywać całą wartośćnavController
. To podejście jest zgodne z najlepszymi praktykami udostępniania zdarzeń z funkcji kompozycyjnych wywołującym i utrzymujenavController
jako jedyne źródło danych.Dane można przekazywać do miejsca docelowego, tworząc instancję klasy trasy zdefiniowanej dla tego miejsca docelowego. Można go następnie uzyskać bezpośrednio z pozycji na liście wstecznej w miejscu docelowym lub z
ViewModel
za pomocąSavedStateHandle.toRoute()
.@Composable fun SampleNavHost( navController: NavHostController ) { NavHost(navController = navController, startDestination = First) { composable<First> { FirstScreen( onButtonClick = { // findNavController().navigate(firstScreenToSecondScreenAction) navController.navigate(Second(id = "ABC")) } ) } composable<Second> { backStackEntry -> val secondRoute = backStackEntry.toRoute<Second>() SecondScreen( id = secondRoute.id, onIconClick = { // findNavController().navigate(secondScreenToThirdScreenAction) navController.navigate(Third) } ) } // ... } }
Usuń wszystkie fragmenty, odpowiednie układy XML, niepotrzebną nawigację i inne zasoby oraz nieaktualne zależności fragmentów i nawigacji Jetpack.
Te same czynności z większą liczbą szczegółów dotyczących Navigation Compose znajdziesz w dokumentacji konfiguracji.
Częste przypadki użycia
Niezależnie od tego, którego komponentu Navigation używasz, obowiązują te same zasady nawigacji.
Typowe przypadki użycia podczas migracji to:
- Przechodzenie do funkcji kompozycyjnej
- Nawigowanie za pomocą argumentów
- Precyzyjne linki
- Zagnieżdżona nawigacja
- Integracja z dolnym paskiem nawigacyjnym
- Integracja z komponentem nawigacji niestandardowej
Więcej informacji o tych przypadkach użycia znajdziesz w artykule Nawigacja za pomocą funkcji Compose.
Pobieranie złożonych danych podczas nawigacji
Stanowczo odradzamy przekazywanie złożonych obiektów danych podczas nawigacji. Zamiast tego podczas wykonywania działań związanych z nawigacją przekazuj jako argumenty tylko niezbędne informacje, takie jak unikalny identyfikator lub inny identyfikator. Złożone obiekty należy przechowywać jako dane w jednym źródle informacji, np. w warstwie danych. Więcej informacji znajdziesz w artykule Pobieranie złożonych danych podczas nawigacji.
Jeśli Twoje fragmenty przekazują złożone obiekty jako argumenty, najpierw rozważ refaktoryzację kodu w taki sposób, aby można było przechowywać te obiekty w warstwie danych i pobierać je z niej. Przykłady znajdziesz w repozytorium Now in Android.
Ograniczenia
W tej sekcji opisujemy obecne ograniczenia biblioteki Navigation Compose.
Stopniowa migracja do Navigation Compose
Obecnie nie możesz używać Navigation Compose, jeśli w kodzie nadal używasz fragmentów jako miejsc docelowych. Aby zacząć korzystać z Navigation Compose, wszystkie miejsca docelowe muszą być funkcjami kompozycyjnymi. Możesz śledzić to zgłoszenie funkcji w narzędziu Issue Tracker.
Animacje przejścia
Od wersji Navigation 2.7.0-alpha01 ustawianie niestandardowych przejść, które wcześniej było możliwe w AnimatedNavHost
, jest teraz obsługiwane bezpośrednio w NavHost
. Więcej informacji znajdziesz w informacjach o wersji.
Więcej informacji
Więcej informacji o przechodzeniu na Navigation Compose znajdziesz w tych materiałach:
- Ćwiczenie z zakresu Navigation Compose: poznaj podstawy Navigation Compose w ramach praktycznego ćwiczenia.
- Now in Android repository: w pełni funkcjonalna aplikacja na Androida zbudowana w całości w Kotlinie i Jetpack Compose, która jest zgodna ze sprawdzonymi metodami projektowania i tworzenia aplikacji na Androida oraz zawiera Navigation Compose.
- Migracja aplikacji Sunflower do Jetpack Compose: post na blogu, w którym opisujemy proces migracji aplikacji Sunflower z widoków do Compose, w tym do Navigation Compose.
- Jetnews na każdym ekranie: post na blogu, w którym opisujemy refaktoryzację i migrację aplikacji Jetnews, aby obsługiwała wszystkie ekrany za pomocą Jetpack Compose i Navigation Compose.
Polecane dla Ciebie
- Uwaga: tekst linku jest wyświetlany, gdy język JavaScript jest wyłączony.
- Nawigowanie za pomocą Compose
- Compose i inne biblioteki
- Inne kwestie, które warto wziąć pod uwagę