Mit der Navigation Compose API können Sie in einer Compose-App zwischen Komponenten wechseln und dabei die Komponente, die Infrastruktur und die Funktionen von Jetpack Navigation nutzen.
Auf dieser Seite wird beschrieben, wie Sie im Rahmen der größeren Migration der ansichtenbasierten Benutzeroberfläche zu Jetpack Compose von einer fragmentbasierten Jetpack-Navigation zu Navigation Compose migrieren.
Voraussetzungen für die Migration
Sie können zu Navigation Compose migrieren, sobald Sie alle Ihre Fragmente durch entsprechende Bildschirm-Composeables ersetzt haben. Bildschirm-Composeables können eine Mischung aus Compose- und Ansichtsinhalten enthalten. Alle Navigationsziele müssen jedoch Composeables sein, damit die Migration von Navigations-Composes möglich ist. Bis dahin sollten Sie die fragmentbasierte Navigationskomponente in Ihrer Interoperabilitätsansicht und Compose-Codebasis weiterhin verwenden. Weitere Informationen finden Sie in der Dokumentation zur Navigationsinteroperabilität.
Die Verwendung von Navigation Compose in einer reinen Compose-App ist keine Voraussetzung. Sie können die fragmentbasierte Navigationskomponente weiterhin verwenden, solange Sie Fragmente zum Hosten Ihrer zusammensetzbaren Inhalte beibehalten.
Migrationsschritte
Unabhängig davon, ob Sie unserer empfohlenen Migrationsstrategie folgen oder einen anderen Ansatz verfolgen, werden Sie irgendwann an den Punkt kommen, an dem alle Navigationsziele Screen Composeables sind und Fragmente nur als Composeable-Container dienen. In dieser Phase können Sie zu Navigation Compose migrieren.
Wenn Ihre App bereits einem UDF-Designmuster und unserem Leitfaden zur Architektur folgt, sollte die Migration zu Jetpack Compose und Navigation Compose abgesehen von der UI-Ebene keine größeren Refactorings anderer Schichten Ihrer App erfordern.
So migrieren Sie zu Navigation Compose:
- Fügen Sie Ihrer App die Navigation Compose-Abhängigkeit hinzu.
Erstellen Sie ein
App-level
-Komposit und fügen Sie es IhremActivity
als Einstiegspunkt für die Zusammenstellung hinzu. Ersetzen Sie damit die Einrichtung des Ansichtslayouts:class SampleActivity : ComponentActivity() { override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) // setContentView<ActivitySampleBinding>(this, R.layout.activity_sample) setContent { SampleApp(/* ... */) } } }
Erstellen Sie Typen für jedes Navigationsziel. Verwenden Sie
data object
für Ziele, für die keine Daten erforderlich sind, unddata class
oderclass
für Ziele, für die Daten erforderlich sind.@Serializable data object First @Serializable data class Second(val id: String) @Serializable data object Third
Richte die
NavController
an einem Ort ein, an dem alle Composeables, die darauf verweisen müssen, darauf zugreifen können. Normalerweise befindet sie sich imApp
-Composeable. Dieser Ansatz folgt den Grundsätzen des Zustands-Hoisting und ermöglicht es,NavController
als vertrauenswürdige Quelle für die Navigation zwischen zusammensetzbaren Bildschirmen und die Aufrechterhaltung des Backstacks zu verwenden:@Composable fun SampleApp() { val navController = rememberNavController() // ... }
Erstellen Sie die
NavHost
Ihrer App imApp
-Komposit und übergeben Sie dienavController
:@Composable fun SampleApp() { val navController = rememberNavController() SampleNavHost(navController = navController) } @Composable fun SampleNavHost( navController: NavHostController ) { NavHost(navController = navController, startDestination = First) { // ... } }
Fügen Sie die
composable
Ziele hinzu, um Ihren Navigationsgraphen zu erstellen. Wenn jeder Bildschirm bereits zu Compose migriert wurde, besteht dieser Schritt nur aus dem Extrahieren dieser Bildschirm-Composeables aus Ihren Fragmenten in diecomposable
-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(/* ... */) } // ... } }
Wenn Sie der Anleitung zum Entwerfen der Compose-Benutzeroberfläche gefolgt sind, insbesondere dazu, wie
ViewModel
s und Navigationsereignisse an Composables übergeben werden sollten, müssen Sie im nächsten Schritt ändern, wie Sie dieViewModel
für jedes Bildschirm-Composeable bereitstellen. Sie können die Hilt-Injection und den Integrationspunkt mit Compose und Navigation überhiltViewModel
häufig verwenden:@Composable fun FirstScreen( // viewModel: FirstViewModel = viewModel(), viewModel: FirstViewModel = hiltViewModel(), onButtonClick: () -> Unit = {}, ) { // ... }
Ersetzen Sie alle
findNavController()
-Navigationsanrufe durchnavController
-Anrufe und übergeben Sie diese als Navigationsereignisse an jeden zusammensetzbaren Bildschirm, anstatt die gesamtenavController
zu übergeben. Dieser Ansatz folgt den Best Practices, Ereignisse aus kombinierbaren Funktionen für Aufrufer freizugeben, und behält dienavController
als Single Source of Truth bei.Daten können an ein Ziel übergeben werden, indem eine Instanz der für dieses Ziel definierten Routenklasse erstellt wird. Sie kann dann entweder direkt aus dem Backstack-Eintrag am Ziel oder über ein
ViewModel
mitSavedStateHandle.toRoute()
abgerufen werden.@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) } ) } // ... } }
Entfernen Sie alle Fragmente, relevanten XML-Layouts, unnötige Navigations- und andere Ressourcen sowie veraltete Fragment- und Jetpack Navigation-Abhängigkeiten.
Dieselben Schritte mit weiteren Details zu Navigation Compose finden Sie in der Einrichtungsdokumentation.
Gängige Anwendungsfälle
Unabhängig davon, welche Navigationskomponente Sie verwenden, gelten dieselben Navigationsprinzipien.
Gängige Anwendungsfälle für die Migration:
- Zu einem Composeable wechseln
- Mit Argumenten navigieren
- Deep links
- Verschachtelte Navigation
- Einbindung in die untere Navigationsleiste
- Einbindung in eine benutzerdefinierte Navigationskomponente
Weitere Informationen zu diesen Anwendungsfällen finden Sie unter Mit Compose navigieren.
Komplexe Daten bei der Navigation abrufen
Wir empfehlen dringend, bei der Navigation keine komplexen Datenobjekte zu übergeben. Geben Sie stattdessen die minimal erforderlichen Informationen, z. B. eine eindeutige Kennung oder eine andere Art von ID, als Argumente an, wenn Sie Navigationsaktionen ausführen. Komplexe Objekte sollten als Daten in einer einzigen zentralen Informationsquelle gespeichert werden, z. B. in der Datenebene. Weitere Informationen finden Sie unter Abrufen komplexer Daten beim Navigieren.
Wenn Ihre Fragmente komplexe Objekte als Argumente übergeben, sollten Sie Ihren Code zuerst so umstrukturieren, dass diese Objekte in der Datenebene gespeichert und abgerufen werden können. Beispiele finden Sie im Repository „Jetzt in Android“.
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 in Ihrem Code weiterhin Fragmente als Ziele verwenden. Damit Sie Navigation Compose verwenden können, müssen alle Ziele Composables sein. Sie können den Status dieser Funktionsanfrage im Issue Tracker verfolgen.
Übergangsanimationen
Ab Navigation 2.7.0-alpha01 wird die Einstellung benutzerdefinierter Übergänge, die bisher über AnimatedNavHost
erfolgte, jetzt direkt über NavHost
unterstützt. Weitere Informationen finden Sie in den Versionshinweisen.
Weitere Informationen
Weitere Informationen zur Migration zu Navigation Compose finden Sie in den folgenden Ressourcen:
- Codelab zu Navigation Compose: In diesem Codelab lernen Sie die Grundlagen von Navigation Compose kennen.
- Jetzt im Android-Repository: Eine voll funktionsfähige Android-App, die vollständig mit Kotlin und Jetpack Compose entwickelt wurde, die den Best Practices für Android-Design und -Entwicklung folgt und Navigation Compose enthält.
- Sunflower zu Jetpack Compose migrieren: In diesem Blogpost wird die Migration der Beispiel-App „Sunflower“ von Views zu Compose dokumentiert, einschließlich der Migration zu Navigation Compose.
- Jetnews für alle Bildschirme: In diesem Blogpost wird die Umstrukturierung und Migration des Jetnews-Beispiels beschrieben, um alle Bildschirme mit Jetpack Compose und Navigation Compose zu unterstützen.
Empfehlungen für dich
- Hinweis: Der Linktext wird angezeigt, wenn JavaScript deaktiviert ist.
- Mit Compose navigieren
- Compose und andere Bibliotheken
- Weitere Hinweise