Jetpack Navigation zu Navigation Compose migrieren

Mit der Navigation Compose API können Sie zwischen zusammensetzbaren Funktionen in einem Compose-Anwendung erstellen und gleichzeitig die Komponente Jetpack Navigation nutzen, Infrastruktur und Funktionen.

Auf dieser Seite wird beschrieben, wie Sie von einer fragmentierten Jetpack-Navigation zu Navigation Compose ist Teil der größeren, ansichtsbasierten UI-Migration zu Jetpack. Schreiben.

Voraussetzungen für die Migration

Sie können zu „Navigation Compose“ migrieren, sobald Sie Ihre gesamten Fragmente mit entsprechenden zusammensetzbaren Bildschirmen Zusammensetzbare Funktionen des Bildschirms können eine Mischung aus "Inhalt erstellen" und "Inhalt ansehen", aller Navigationsziele müssen jedoch componables, um die Migration von „Navigation Compose“ zu aktivieren. Bis dahin sollten Sie Verwenden Sie weiterhin die Komponente für die fragmentierte Navigation in Ihrer Interoperabilitätsansicht und Codebasis erstellen Weitere Informationen finden Sie in der Dokumentation zur Navigations-Interop. Informationen.

Die Verwendung der Funktion „Navigation Compose“ in einer reinen Schreibanwendung ist keine Voraussetzung. Sie können weiterhin die Komponente für die fragmentierte Navigation verwenden, Fragmente zum Hosting Ihrer zusammensetzbaren Inhalte

Migrationsschritte

Ob Sie nun unsere empfohlene Migrationsstrategie nutzen oder erreichen Sie einen Punkt, an dem alle Navigationsziele zusammensetzbare Bildschirme, wobei Fragmente nur als zusammensetzbare Container fungieren. In dieser können Sie zu „Navigation Compose“ migrieren.

Wenn Ihre App bereits einem UDF-Designmuster folgt, und unserem Leitfaden zur Architektur durchgeführt werden, sollte die Migration zu Jetpack Compose und Navigation Compose Sie erfordern größere Refaktorierungen anderer Ebenen Ihrer App, abgesehen von der UI-Ebene.

So migrieren Sie zu „Navigation Compose“:

  1. Fügen Sie Ihrer App die Navigation Compose-Abhängigkeit hinzu.
  2. Erstellen Sie eine zusammensetzbare Funktion App-level und fügen Sie sie dem Activity als Erstellen Sie den Einstiegspunkt und ersetzen Sie dabei die Einrichtung des Ansichtslayouts:

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

  3. Richten Sie die NavController an einem Ort ein, an dem alle zusammensetzbaren Funktionen vorhanden sind, die Zugriff darauf haben (diese befindet sich normalerweise in der App zusammensetzbar). Dieser Ansatz folgt den Prinzipien des Zustandshebens und ermöglicht Ihnen, NavController als „Source of Truth“ für die Navigation zu verwenden zwischen zusammensetzbaren Bildschirmen und der Pflege des Back-Stacks:

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

  4. Erstellen Sie das NavHost Ihrer App in der zusammensetzbaren App und übergeben Sie den navController:

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

  5. Fügen Sie die composable-Ziele hinzu, um die Navigationsgrafik zu erstellen. Wenn jede Bildschirm zuvor zu „Schreiben“ migriert wurde, besteht dieser Schritt nur Diese zusammensetzbaren Funktionen des Bildschirms werden aus Ihren Fragmenten in das composable extrahiert Ziele:

    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. Wenn Sie der Anleitung zum Erstellen Ihrer Compose-UI gefolgt sind: insbesondere wie ViewModels und Navigationsereignisse an zusammensetzbare Funktionen verwenden, ändern Sie im nächsten Schritt, wie Sie die ViewModel jeder Bildschirm zusammensetzbar ist. Sie können Hilt Injection und die Punkt mit „Schreiben“ und „Navigation über hiltViewModel“:

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

  7. Alle findNavController()-Navigationsaufrufe durch navController ersetzen und übergeben diese als Navigationsereignisse an jeden zusammensetzbaren Bildschirm, anstatt als die gesamte navController zu übergeben. Dieser Ansatz entspricht dem besten Praktiken, wie Ereignisse aus zusammensetzbaren Funktionen für Aufrufer und behält navController die zentrale Informationsquelle bei.

    1. Wenn Sie zuvor das Safe Args-Plug-in zum Generieren Navigationsanweisungen und -aktionen einfügen, ersetzen Sie sie durch eine Route – ein Stringpfad zu Ihrer zusammensetzbaren Funktion, der für jedes Ziel eindeutig ist.
    2. Informationen zum Ersetzen von sicheren Argumenten beim Übergeben von Daten finden Sie unter Navigation mit Argumente.
    3. Informationen zur Schriftsicherheit in „Navigation Compose“ findest du im Abschnitt Sichere Argumente unten.

      @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. Entfernen Sie alle Fragmente, relevanten XML-Layouts, unnötigen Navigationselemente und andere sowie veraltete Fragment- und Jetpack-Navigationsabhängigkeiten.

Dieselben Schritte finden Sie auch in der Dokumentation zur Einrichtung

Gängige Anwendungsfälle

Unabhängig von der verwendeten Navigationskomponente gelten dieselben Prinzipien Navigation anwenden.

Häufige Anwendungsfälle bei der Migration:

Weitere Informationen zu diesen Anwendungsfällen finden Sie unter Navigation mit Schreiben:

Safe Args

Im Gegensatz zu Jetpack Navigation unterstützt Navigation Compose nicht die Verwendung der Safe Args-Plug-in zur Codegenerierung. Stattdessen können Sie Typsicherheit mit Navigation Compose, indem Sie Ihren Code so strukturieren, dass er typsicher ist. Laufzeit.

Komplexe Daten beim Navigieren abrufen

Navigation Compose ist routenbasiert und im Gegensatz zu Jetpack Navigation können benutzerdefinierte Parcelables und Serializables nicht als Argumente übergeben.

Wir raten dringend davon ab, bei der Navigation komplexe Datenobjekte zu übergeben. Geben Sie stattdessen die mindestens erforderlichen Informationen an, etwa eine eindeutige Kennung oder andere Art von ID als Argumente beim Ausführen von Navigationsaktionen. Sie sollten Speichern komplexer Objekte als Daten in einer einzigen verlässlichen Quelle, z. B. die Daten Ebene Weitere Informationen finden Sie unter Komplexe Daten abrufen, wenn Navigation.

Wenn Ihre Fragmente komplexe Objekte als Argumente übergeben, sollten Sie eine Refaktorierung in Betracht ziehen und zwar so, dass diese Objekte gespeichert und aus dem mit der Datenschicht. Weitere Informationen finden Sie im Repository „Now in Android“ für Beispiele.

Beschränkungen

In diesem Abschnitt werden die aktuellen Einschränkungen für „Navigation Compose“ beschrieben.

Inkrementelle Migration zu „Navigation Compose“

Derzeit können Sie „Navigation Compose“ nicht verwenden, wenn Sie weiterhin Fragmente als Ziele in Ihrem Code an. Um die Funktion „Navigation Compose“ zu verwenden, Ziele müssen zusammensetzbar sein. Diese Funktion können Sie auf der Problemverfolgung.

Übergangsanimationen

Ab Navigation 2.7.0-alpha01, Unterstützung für das Festlegen benutzerdefinierter (bisher AnimatedNavHost) werden jetzt direkt in NavHost unterstützt. Lesen Sie die Versionshinweise. .

Weitere Informationen

Weitere Informationen zur Migration zu Navigation Compose finden Sie in den Ressourcen:

  • Codelab „Navigation Compose“: Hier lernen Sie die Grundlagen von „Navigation Compose“ mit ein praxisorientiertes Codelab.
  • Now in Android-Repository: eine voll funktionsfähige Android-App Vollständig mit Kotlin und Jetpack Compose erstellt, das dem Android-Design folgt und Best Practices für die Entwicklung. Dazu gehört „Navigation Compose“.
  • Sunflower zu Jetpack Compose migrieren: Ein Blogpost, der dokumentiert den Migrationsprozess der Sunflower-Beispiel-App von Views zu Compose, was auch die Migration zu Navigation Compose umfasst.
  • Jetnews for Everyscreen: Ein Blogpost, in dem die Refaktorierung und Migration des Jetnews-Beispiels, um alle Bildschirme mit Jetpack Compose und Navigation Compose.