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ć treści z 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, który jest używany w ramach interoperacyjności, 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żyj
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 docomposable
miejsc docelowych: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 kompozycją, zamiast przekazywać całą wartośćfindNavController()
.navController
To podejście jest zgodne ze sprawdzonymi metodami 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 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 Navigation Compose: poznaj podstawy Navigation Compose w praktyce.
- 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 JavaScript jest wyłączony.
- Nawigacja za pomocą funkcji Komponuj
- Compose i inne biblioteki
- Inne kwestie, które warto wziąć pod uwagę