Navigation auf faltbaren Geräten

Die Foldable Navigation-Komponente ist eine Bibliothek, die auf der Android-Navigationskomponente basiert. Sie hilft Entwicklern, Fragmentnavigation für verschiedene Bildschirmmodi zu implementieren oder eine vorhandene Anwendung an ein Navigationsmuster für faltbare Geräte anzupassen.

Die Foldable Navigation-Komponente besteht aus drei Hauptteilen:

  • Navigationsdiagramm: eine XML-Ressource, die alle navigationsbezogenen Informationen an einem zentralen Speicherort enthält. Dies ist der gleiche Speicherort, der von der von Google bereitgestellten Navigationskomponente verwendet wird.
  • FoldableNavHost: ein leerer Container, der Ziele aus Ihrem Navigationsdiagramm anzeigt. Die Implementierung für die Navigation auf faltbaren Geräten ist FoldableNavHostFragment.
  • FoldableNavController: ein Objekt, das die App-Navigation innerhalb eines FoldableNavHost verwaltet.

Übersicht

Anwendungen auf Dual-Screen- und faltbaren Geräten können auf einem einzelnen Bildschirm oder das Faltfeature überspannend angezeigt werden. Beim ersten Start der Anwendung:

  • Bei Darstellung auf einem Einzelbildschirm ist nur ein Fragment (A) sichtbar.
  • Wenn die Anwendung über ein Faltfeature hinweg gerendert wird, befindet sich das erste Fragment (A) auf der ersten Seite der Faltung, und die andere Seite der Faltung ist leer.

Wenn Sie vom Anfangszustand zu einem anderen Fragment (B) navigieren, wird das neue Fragment auf dem Endbildschirm geöffnet.

Wenn der Benutzer zu einem dritten Fragment (C) navigiert, wird es auf dem Endbildschirm angezeigt, das vorherige Fragment (B) wird auf den Startbildschirm verschoben.

  • Wenn die App von der übergreifenden Darstellung auf einen Einzelbildschirm verschoben wird, werden alle Fragmente vom Endbildschirm auf den Startbildschirm verschoben, und (C) wird zuoberst angezeigt.
  • Wenn die App von einem Einzelbildschirm über die Faltung oder das Scharnier hinweg zur übergreifenden Darstellung umgestellt wird und der Navigationsstapel mehr als zwei Fragmente enthält, wird das letzte Fragment auf den Endbildschirm verschoben.

Six different dual-screen examples demonstrating how fragments A, B, and C would appear after different navigation steps

Ändern des Anzeigebereichsziels für Aktionen

Mithilfe des launchScreen-Attributs im Navigationsdiagramm können Sie angeben, wo ein neues Fragment angezeigt wird. Dies sind die möglichen Werte für launchScreen:

  • start: Das Fragment wird auf dem ersten Bildschirm geöffnet
  • end: Das Fragment wird auf dem zweiten Bildschirm geöffnet
  • both: Das Fragment überspannt den gesamten Anzeigebereich

In diesem XML-Navigationsbeispiel wird die Verwendung dieses Attributs veranschaulicht:

<navigation xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:id="@+id/home"
    app:startDestination="@+id/titleScreen">

    <fragment
        android:id="@+id/titleScreen"
        android:name="com.microsoft.device.dualscreen.navigation.sample.homescreen.TitleFragment"
        android:label="@string/title_home"
        tools:layout="@layout/fragment_title">
        <action
            android:id="@+id/action_title_to_about"
            app:launchScreen="end"
            app:destination="@id/aboutScreen"
            app:enterAnim="@anim/slide_in_right"
            app:exitAnim="@anim/slide_out_left"
            app:popEnterAnim="@anim/slide_in_right"
            app:popExitAnim="@anim/slide_out_left" />
    </fragment>
</navigation>

Wichtig

Dieses Attribut kann nur durch direktes Bearbeiten der XML-Datei geändert werden. Es kann nicht im Android Studio-Editor geändert werden.

Beispiel

Sie können diese Navigationsbeispiel-App herunterladen, um all diese Verhaltensweisen zu sehen.

Importieren der Bibliothek in dein Projekt

  1. Fügen Sie die Abhängigkeit der Datei „build.gradle“ auf Modulebene hinzu:

    dependencies {
       def nav_version = "1.0.0-alpha3"
       implementation "com.microsoft.device.dualscreen:navigation-fragment-ktx:$nav_version"
       implementation "com.microsoft.device.dualscreen:navigation-ui-ktx:$nav_version"
    }
    

  1. Wenn dein Projekt mit Java erstellt wird, musst du deiner Datei „build.gradle“ auf Modulebene eine „kotlin-stdlib“-Abhängigkeit hinzufügen. (Der Grund hierfür ist, dass ein Teil der Bibliothek mit Kotlin erstellt wurde.)

    dependencies {
       implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk8:$kotlin_version"
    }
    

Diese Komponenten bauen auf der von Google bereitgestellten Navigationskomponente auf, daher weist die Foldable-Navigation-Bibliothek eine Abhängigkeit von dieser auf.

Erstellen eines Navigationsdiagramms

Ein Navigationsdiagramm ist eine XML-Ressourcendatei mit allen Navigationspfaden Ihrer App, die Ziele und Aktionen verwendet. Das Navigationsdiagramm kann über den Android Studio-Navigations-Editor oder manuell mithilfe eines XML-Editors erstellt werden. Weitere Informationen finden Sie unter Erstellen eines Navigationsdiagramms.

Hinzufügen eines NavHost zu einer Aktivität

Die Navigationskomponente für faltbare Geräte wurde für Apps mit einer Hauptaktivität und mehreren Fragmentzielen konzipiert. Die Hauptaktivität ist einem Navigationsdiagramm zugeordnet und enthält ein FoldableNavHostFragment, das für den Austausch von Fragmentzielen zuständig ist. Wenn Ihre App mehr als eine Aktivität hat, gilt für jede Aktivität ein eigenes Navigationsdiagramm.

Dies ist ein Beispiel für eine XML-Layoutdatei für die Hauptaktivität, das zeigt, wie das app:navGraph-Attribut festgelegt wird:

<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:id="@+id/surface_duo_layout"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <androidx.fragment.app.FragmentContainerView
        android:id="@+id/nav_host_fragment"
        android:name="androidx.navigation.FoldableNavHostFragment"
        android:layout_width="0dp"
        android:layout_height="0dp"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintRight_toRightOf="parent"
        app:layout_constraintTop_toTopOf="parent"
        app:navGraph="@navigation/nav_graph" />
</androidx.constraintlayout.widget.ConstraintLayout>

FoldableNavHost kann auch programmgesteuert festgelegt werden:

val navHostFragment = FoldableNavHostFragment.create(navGraphId)
fragmentManager.beginTransaction()
    .add(containerId, navHostFragment, fragmentTag)
    .commitNow()

Weitere Informationen zum Hinzufügen von FoldableNavHost finden Sie unter Hinzufügen eines NavHost zu einer Aktivität.

Dieser Codeausschnitt kann verwendet werden, um gemäß den Navigationsregeln für faltbare Geräte zu Fragmenten zu navigieren:

class SomeFragment : Fragment() {
    override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
        super.onViewCreated(view, savedInstanceState)

        view.findViewById<Button>(R.id.btn_next).setOnClickListener {
            findFoldableNavController().navigate(R.id.action_next)
        }
    }
}

Aktualisieren von Benutzeroberflächenkomponenten mit FoldableNavigationUI

FoldableNavigationUI ist eine ähnliche Komponente wie NavigationUI in der Jetpack-Navigationskomponente und enthält statische Methoden, die die Navigation mit der oberen Leiste der App, dem Navigations-Drawer und dem unteren Navigationsmenü verwalten. Weitere Informationen finden Sie hier:

FoldableNavigationUI enthält die folgenden Methoden, die den von NavigationUI bereitgestellten ähnlich sind:

// same method name, with foldable parameter
boolean onNavDestinationSelected(MenuItem item, FoldableNavController navController)
boolean navigateUp(FoldableNavController navController, Openable openableLayout)
boolean navigateUp(FoldableNavController navController, FoldableAppBarConfiguration configuration)
// method name changed to reflect foldable navigation
void setupActionBarWithFoldableNavController(AppCompatActivity activity, FoldableNavController navController)
void setupActionBarWithFoldableNavController(AppCompatActivity activity, FoldableNavController navController, Openable openableLayout)
void setupActionBarWithFoldableNavController(AppCompatActivity activity, FoldableNavController navController, FoldableAppBarConfiguration configuration)
void setupWithFoldableNavController(Toolbar toolbar, FoldableNavController navController)
void setupWithFoldableNavController(Toolbar toolbar, FoldableNavController navController, Openable openableLayout)
void setupWithFoldableNavController(Toolbar toolbar, FoldableNavController navController, FoldableAppBarConfiguration configuration)
void setupWithFoldableNavController(CollapsingToolbarLayout collapsingToolbarLayout, Toolbar toolbar, FoldableNavController navController)
void setupWithFoldableNavController(CollapsingToolbarLayout collapsingToolbarLayout, Toolbar toolbar, FoldableNavController navController, Openable openableLayout)
void setupWithFoldableNavController(CollapsingToolbarLayout collapsingToolbarLayout, Toolbar toolbar, FoldableNavController navController, FoldableAppBarConfiguration configuration)
void setupWithFoldableNavController(NavigationView navigationView, FoldableNavController navController)
void setupWithFoldableNavController(BottomNavigationView bottomNavigationView, FoldableNavController navController)

Migrieren vorhandener Anwendungen zur Navigation für faltbare Geräte

Vorhandenen Anwendungen, die die von Google bereitgestellte Navigationskomponente verwenden, kann durch Ausführen der folgenden Schritte Funktionalität für faltbare Geräte hinzugefügt werden:

  1. Verwenden Sie FoldableNavHostFragment anstelle von NavHostFragment in der Fragmentcontaineransicht, indem Sie dies ändern:

    <androidx.fragment.app.FragmentContainerView
         android:id="@+id/nav_host_fragment"
         android:name="androidx.navigation.NavHostFragment"
    

    zu

    <androidx.fragment.app.FragmentContainerView
         android:id="@+id/nav_host_fragment"
         android:name="androidx.navigation.FoldableNavHostFragment"
    
  2. Verwenden Sie findFoldableNavController, um die Instanz für FoldableNavController abzurufen, und verwenden Sie sie zum Navigieren innerhalb des Navigationsdiagramms, indem Sie dies ändern:

    findNavController().navigate(R.id.action_next)
    

    zu

    findFoldableNavController().navigate(R.id.action_next)
    
  3. Verwenden Sie durch diese Änderung FoldableNavigationUI anstelle von NavigationUI:

    val navHostFragment = supportFragmentManager.findFragmentById(R.id.nav_host_fragment) as NavHostFragment
    val navController = navHostFragment.navController
    val appBarConfiguration = AppBarConfiguration(navController.graph)
    setupActionBarWithNavController(navController, appBarConfiguration)
    

    in

    val navHostFragment = supportFragmentManager.findFragmentById(R.id.nav_host_fragment) as FoldableNavHostFragment
    val navController = navHostFragment.navController
    val appBarConfiguration = FoldableAppBarConfiguration(navController.graph)
    setupActionBarWithFoldableNavController(navController, appBarConfiguration)