Przenieś nawigację Jetpack do tworzenia wiadomości w Nawigacji

Interfejs Navigation Compose API pozwala poruszać się między elementami kompozycyjnymi w aplikacji Compose przy użyciu komponentu, infrastruktury i funkcji Jetpack Navigation.

Na tej stronie opisujemy, jak przejść z nawigacji Jetpack opartej na fragmentach na platformę Jetpack Compose w ramach szerszej migracji opartej na widoku interfejsu do Jetpack Compose.

Wymagania wstępne migracji

Możesz przejść na funkcję Navigation Compose, gdy będziesz w stanie zastąpić wszystkie fragmenty kodu odpowiednimi elementami kompozycyjnymi ekranu. Elementy kompozycyjne ekranu mogą zawierać połączenie treści tworzenia i wyświetlania, ale aby można było przenieść narzędzie Navigation Compose, wszystkie miejsca docelowe nawigacji muszą być kompozycyjne. Do tego czasu używaj komponentu nawigacji opartej na fragmentach w widoku interoperacyjności i bazie kodu tworzenia wiadomości. Więcej informacji znajdziesz w dokumentacji interoperacyjności nawigacji.

Korzystanie z funkcji tworzenia nawigacji w aplikacji tylko do tworzenia wiadomości nie jest wymagane. Możesz nadal korzystać z komponentu nawigacji opartego na fragmentach, jeśli zachowasz fragmenty do hostowania treści kompozycyjnych.

Etapy migracji

Niezależnie od tego, czy będziesz trzymać się naszej zalecanej strategii migracji, czy wybrać inne podejście, dotrzesz do punktu, w którym wszystkie miejsca docelowe nawigacji będą funkcjami kompozycyjnymi ekranu, a fragmenty kodu będą działać tylko jako kontenery kompozycyjne. Na tym etapie możesz przejść do Navigation Compose.

Jeśli Twoja aplikacja jest już zgodna ze wzorcem projektu UDF i naszym przewodnikiem po architekturze, migracja do Jetpack Compose i nawigacji Compose nie powinna wymagać dużych refaktoryzacji innych warstw aplikacji poza warstwą interfejsu.

Aby przenieść dane do Navigation Compose, wykonaj te czynności:

  1. Dodaj do swojej aplikacji zależność nawigacji.
  2. Utwórz kompozycję App-level i dodaj ją do elementu Activity jako punkt wejścia tworzenia wiadomości, zastępując konfigurację układu widoku:

    class SampleActivity : ComponentActivity() {
    
        override fun onCreate(savedInstanceState: Bundle?) {
            super.onCreate(savedInstanceState)
            // setContentView<ActivitySampleBinding>(this, R.layout.activity_sample)
            setContent {
                SampleApp(/* ... */)
            }
        }
    }

  3. Skonfiguruj NavController w miejscu, w którym wszystkie elementy kompozycyjne, które muszą się do niego odwoływać, mają do niego dostęp (zazwyczaj znajduje się on w elemencie kompozycyjnym App). Takie podejście jest zgodne z zasadami przenoszenia stanu i umożliwia korzystanie z platformy NavController jako źródła informacji, które służy do poruszania się między ekranami kompozycyjnymi i utrzymywania „stosu tylnego”:

    @Composable
    fun SampleApp() {
        val navController = rememberNavController()
        // ...
    }

  4. Utwórz NavHost swojej aplikacji w funkcji kompozycyjnej aplikacji i przekaż navController:

    @Composable
    fun SampleApp() {
        val navController = rememberNavController()
    
        SampleNavHost(navController = navController)
    }
    
    @Composable
    fun SampleNavHost(
        navController: NavHostController
    ) {
        NavHost(navController = navController, startDestination = "first") {
            // ...
        }
    }

  5. Dodaj miejsca docelowe (composable), aby utworzyć wykres nawigacji. Jeśli każdy ekran został wcześniej przeniesiony do Compose, ten krok składa się tylko z wyodrębnienia tych elementów kompozycyjnych ekranowych z fragmentów kodu do miejsc docelowych composable:

    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(/* ... */)
            }
            // ...
        }
    }

  6. Jeśli postępujesz zgodnie ze wskazówkami dotyczącymi tworzenia architektury interfejsu tworzenia wiadomości, a zwłaszcza sposobu przekazywania elementów ViewModel i zdarzeń nawigacji do funkcji kompozycyjnych, następnym krokiem jest zmiana sposobu przesyłania ViewModel na każdy ekran z możliwością kompozycji. W hiltViewModel często możesz korzystać z wstrzykiwania Hilt oraz jego punktu integracji z tworzeniem wiadomości i Nawigacją:

    @Composable
    fun FirstScreen(
        // viewModel: FirstViewModel = viewModel(),
        viewModel: FirstViewModel = hiltViewModel(),
        onButtonClick: () -> Unit = {},
    ) {
        // ...
    }

  7. Zastąp wszystkie wywołania nawigacyjne findNavController() jednym z navController i przekazuj je jako zdarzenia nawigacji do każdego ekranu kompozycyjnego, zamiast przekazywać cały navController. To podejście jest zgodne ze sprawdzonymi metodami udostępniania zdarzeń z funkcji kompozycyjnych elementom wywołującym i utrzymuje navController jako jedyne źródło prawdy.

    1. Jeśli używasz wtyczki Safe Args do generowania wskazówek dojazdu i działań nawigacji, zastąp ją trasą – ścieżką ciągu tekstowego do funkcji kompozycyjnej, niepowtarzalnej dla każdego miejsca docelowego.
    2. Informacje o zastępowaniu bezpiecznych argumentów podczas przekazywania danych znajdziesz w sekcji Nawigacja za pomocą argumentów.
    3. Aby dowiedzieć się, jak zapewnić bezpieczeństwo typów w funkcji Navigation Compose, przeczytaj sekcję Bezpieczne argumenty poniżej.

      @Composable
      fun SampleNavHost(
          navController: NavHostController
      ) {
          NavHost(navController = navController, startDestination = "first") {
              composable("first") {
                  FirstScreen(
                      onButtonClick = {
                          // findNavController().navigate(firstScreenToSecondScreenAction)
                          navController.navigate("second_screen_route")
                      }
                  )
              }
              composable("second") {
                  SecondScreen(
                      onIconClick = {
                          // findNavController().navigate(secondScreenToThirdScreenAction)
                          navController.navigate("third_screen_route")
                      }
                  )
              }
              // ...
          }
      }

  8. Usuń wszystkie fragmenty, odpowiednie układy XML, zbędne elementy nawigacyjne i inne zasoby oraz nieaktualne zależności fragmentów kodu Fragment i Jetpack Navigation.

Te same kroki znajdziesz w dokumentacji dotyczącej konfiguracji zawierającej więcej informacji związanych z tworzeniem nawigacji.

Częste zastosowania

Niezależnie od używanego komponentu nawigacji obowiązują te same zasady nawigacji.

Oto typowe przypadki użycia:

Więcej informacji o tych przypadkach użycia znajdziesz w artykule Nawigacja przy użyciu tworzenia wiadomości.

Safe Args

W przeciwieństwie do Jetpack Navigation Navigation Compose nie obsługuje wtyczki Safe Args do generowania kodu. Zamiast tego możesz zapewnić bezpieczeństwo pisania w narzędziu Navigation Compose, tworząc taką strukturę kodu w taki sposób, aby był on bezpieczny podczas pisania w środowisku wykonawczym.

Pobieranie złożonych danych podczas nawigacji

Navigation Compose opiera się na trasach w postaci ciągu znaków i w przeciwieństwie do Jetpack Navigation nie obsługuje przekazywania niestandardowych elementów Parcelables i Serializable jako argumentów.

Zdecydowanie odradzamy pomijanie złożonych obiektów danych podczas nawigacji. Zamiast tego podczas wykonywania działań nawigacyjnych przekaż jako argumenty minimalną wymaganą ilość informacji, takich jak unikalny identyfikator lub inny identyfikator. Złożone obiekty należy przechowywać jako dane w jednym źródle wiarygodnych danych, takim jak warstwa danych. Więcej informacji znajdziesz w sekcji Pobieranie złożonych danych podczas nawigacji.

Jeśli fragmenty kodu przekazują złożone obiekty jako argumenty, rozważ najpierw refaktoryzację kodu w sposób umożliwiający przechowywanie i pobieranie tych obiektów z warstwy danych. Przykłady znajdziesz w repozytorium Now w Androidzie.

Ograniczenia

W tej sekcji opisaliśmy obecne ograniczenia funkcji tworzenia nawigacji.

Migracja przyrostowa do Navigation Compose

Obecnie nie możesz korzystać z funkcji Navigation Compose, jeśli nadal używasz fragmentów kodu jako miejsc docelowych w kodzie. Aby można było zacząć korzystać z funkcji Navigation Compose, wszystkie miejsca docelowe muszą być elementami kompozycyjnymi. Możesz śledzić tę prośbę o dodanie funkcji w narzędziu Issue Tracker.

Animacje przejścia

Od Nawigacji w wersji 2.7.0-alfa obsługa ustawiania przejść niestandardowych (wcześniej AnimatedNavHost) jest teraz bezpośrednio obsługiwana w NavHost. Aby dowiedzieć się więcej, przeczytaj informacje o wersji.

Więcej informacji

Więcej informacji na temat migracji do Navigation Compose znajdziesz w tych materiałach:

  • Ćwiczenie z programowania w narzędziu Navigation Compose – opanuj podstawy korzystania z funkcji Navigation Compose w ramach praktycznych ćwiczeń z programowania.
  • Teraz w repozytorium Androida: w pełni funkcjonalna aplikacja na Androida stworzona w całości przy użyciu Kotlin i Jetpack Compose, która jest zgodna ze sprawdzonymi metodami projektowania i tworzenia aplikacji na Androida oraz zawiera Navigation Compose.
  • Migracja Sunflower do Jetpack Compose: post na blogu dokumentujący migrację przykładowej aplikacji Sunflower z Widoki do Compose, która obejmuje też migrację do Navigation Compose.
  • Jetnews na każdy ekran: post na blogu przedstawiający refaktoryzację i migrację próbki Jetnews w celu obsługi wszystkich ekranów w Jetpack Compose i nawigacji.