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

Interfejs Nawigacja Compose API umożliwia poruszanie się między elementami kompozycyjnymi w aplikacji oraz korzystanie z komponentu, infrastruktury i funkcji Jetpack Navigation.

Na tej stronie dowiesz się, jak przejść z nawigacji Jetpack opartej na fragmentach do usługi Navigation Compose w ramach większej migracji interfejsu użytkownika opartej na widokach do Jetpack Compose.

Wymagania wstępne migracji

Możesz przejść do tworzenia nawigacji, gdy będziesz mieć możliwość zastępowania wszystkich fragmentów odpowiednimi funkcjami kompozycyjnymi ekranu. Elementy kompozycyjne ekranu mogą zawierać kombinację tworzenia wiadomości i wyświetlania treści, ale wszystkie miejsca docelowe nawigacji muszą być elementami kompozycyjnymi, aby można było przeprowadzić migrację tworzenia wiadomości w Nawigacji. Do tego czasu korzystaj z komponentu Nawigacja opartego na fragmentach w bazie kodu widoku interoperacyjności i tworzenia wiadomości. Więcej informacji znajdziesz w dokumentacji interoperacyjności nawigacji.

Korzystanie z Nawigacji w tworzeniu wiadomości w aplikacji tylko do tworzenia wiadomości nie jest wymagane. Możesz nadal używać komponentu Nawigacja opartego na fragmentach, o ile zachowasz fragmenty do hostowania treści kompozycyjnej.

Etapy migracji

Bez względu na to, czy stosujesz zalecaną strategię migracji, czy też stosujesz inne podejście, w końcu wszystkie miejsca docelowe nawigacji są funkcjami do tworzenia ekranu, a fragmenty działają tylko jako kontenery kompozycyjne. Na tym etapie możesz przejść do tworzenia w Nawigacji.

Jeśli Twoja aplikacja jest już zgodna z wzorcem projektowania UDF i naszym przewodnikiem po architekturze, migracja do Jetpack Compose i Navigation Compose nie powinna wymagać poważnych refaktoryzacji innych warstw aplikacji oprócz warstwy UI.

Aby przejść do tworzenia wiadomości w Nawigacji, wykonaj te czynności:

  1. Dodaj do aplikacji zależność Nawigacja Compose.
  2. Utwórz kompozycję App-level i dodaj ją do Activity jako punkt początkowy tworzenia, 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 funkcje kompozycyjne, które muszą się do niego odwołać, mają do niego dostęp (zazwyczaj znajduje się to w elemencie kompozycyjnym App). To podejście jest zgodne z zasadami przenoszenia stanu i umożliwia korzystanie z NavController jako źródła informacji do poruszania się między ekranami kompozycyjnymi i utrzymywania stosu wstecznego:

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

  4. Utwórz NavHost 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 nawigacyjny. Jeśli każdy z ekranów został wcześniej przeniesiony do sekcji Utwórz, ten krok polega tylko na wyodrębnieniu z fragmentów ekranu z elementami kompozycyjnymi 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 architektury interfejsu tworzenia wiadomości, a konkretnie tego, w jaki sposób elementy ViewModel i zdarzenia nawigacji powinny być przekazywane do funkcji kompozycyjnych, następnym krokiem jest zmiana sposobu udostępniania elementu ViewModel do każdego ekranu. Często można stosować wstrzykiwanie Hilt i jego punkt integracji z tworzeniem wiadomości i nawigacją w hiltViewModel:

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

  7. Zastąp wszystkie wywołania nawigacji findNavController() wywołaniami navController i przekazuj je jako zdarzenia nawigacji do każdego ekranu z możliwością tworzenia, zamiast przekazywać cały obiekt navController. To podejście jest zgodne ze sprawdzonymi metodami dotyczącymi ujawniania zdarzeń z funkcji kompozycyjnych elementom wywołującym i sprawia, że navController pozostaje jedynym źródłem informacji.

    1. Jeśli wcześniej korzystałeś z wtyczki Safe Args do generowania wskazówek nawigacji i działań, zastąp ją routerem, czyli ciągiem znaków do funkcji kompozycyjnej, unikalną dla każdego miejsca docelowego.
    2. Informacje o zastępowaniu bezpiecznych argumentów podczas przekazywania danych znajdziesz w sekcji Nawigowanie za pomocą argumentów.
    3. Aby dowiedzieć się, jak bezpiecznie określić typ zabezpieczeń w Nawigowaniu przy tworzeniu wiadomości, 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, niepotrzebną nawigację i inne zasoby oraz nieaktualne zależności Fragment i Jetpack Navigation.

Te same czynności, a także więcej szczegółów związanych z tworzeniem wiadomości związanych z Nawigacją, znajdziesz w dokumentacji konfiguracji.

Typowe przypadki użycia

Niezależnie od tego, z jakiego komponentu nawigacji korzystasz, obowiązują te same zasady nawigacji.

Oto typowe przypadki użycia:

Więcej informacji o tych przypadkach użycia znajdziesz w artykule Nawigacja za pomocą opcji tworzenia wiadomości.

Safe Args

W przeciwieństwie do Jetpack Navigation funkcja Navigation Compose nie obsługuje generowania kodu przy użyciu wtyczki Safe Args. Zamiast tego możesz bezpiecznie pisać za pomocą funkcji tworzenia wiadomości w nawigacji, tworząc kod tak, aby można go było bezpiecznie pisać w czasie działania.

Pobieranie złożonych danych podczas nawigacji

Tworzenie funkcji nawigacji jest oparte na trasie z użyciem ciągów znaków i, w przeciwieństwie do Jetpack Navigation, nie obsługuje przekazywania niestandardowych obiektów Parcelable i Serializable jako argumentów.

Zdecydowanie odradzamy przekazywanie złożonych obiektów danych podczas nawigacji. Zamiast tego przekaż w argumentach niezbędne informacje, takie jak unikalny identyfikator lub inny identyfikator, jako argumenty podczas wykonywania działań nawigacyjnych. Złożone obiekty należy przechowywać jako dane w jednym źródle wiarygodnych informacji, takim jak warstwa danych. Więcej informacji znajdziesz w artykule Pobieranie złożonych danych podczas nawigacji.

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

Ograniczenia

W tej sekcji opisano obecne ograniczenia dotyczące tworzenia wiadomości w Nawigacji.

Migracja przyrostowa do tworzenia wiadomości w Nawigacji

Obecnie nie można korzystać z nawigacji w celu tworzenia wiadomości, gdy w kodzie miejsca docelowe są używane fragmenty kodu. Aby można było zacząć korzystać z funkcji Nawigacja, wszystkie miejsca docelowe muszą być obiektami kompozycyjnymi. Tę prośbę o dodanie funkcji możesz śledzić w narzędziu do śledzenia błędów.

Animacje przejść

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

Więcej informacji

Więcej informacji o migracji do tworzenia wiadomości w Nawigacji znajdziesz w tych materiałach:

  • Ćwiczenie z programowania dotyczące tworzenia wiadomości w nawigacji – opanuj podstawy tworzenia wiadomości w nawigacji dzięki ćwiczeniom z programowania.
  • Teraz w repozytorium na Androida: w pełni funkcjonalna aplikacja na Androida stworzona w całości z użyciem technologii Kotlin i Jetpack Compose, zgodna ze sprawdzonymi metodami projektowania i tworzenia aplikacji na Androida oraz zawierająca funkcję Navigation Compose.
  • Migracja Sunflower do Jetpack Compose: post na blogu przedstawiający drogę migracji przykładowej aplikacji Sunflower z widoków do tworzenia wiadomości, a także migrację do funkcji Navigation Compose.
  • Jetnews na każdym ekranie: post na blogu zawierający refaktoryzację i migrację przykładowej wersji Jetnews w celu obsługi wszystkich ekranów z użyciem Jetpack Compose i nawigacji Compose.