Navigazione piegabile

Il componente di spostamento piegabile è una libreria basata sul componente di spostamento Android. Consente agli sviluppatori di implementare lo spostamento di frammenti per diverse modalità dello schermo o di adattare un'applicazione esistente al modello di navigazione piegabile;

Il componente di navigazione piegabile è costituito da tre parti chiave:

  • Graph di spostamento: una risorsa XML che contiene tutte le informazioni correlate allo spostamento in una posizione centralizzata. È uguale a quello del componente di navigazione fornito da Google.
  • FoldableNavHost : contenitore vuoto che visualizza le destinazioni dal grafico di spostamento. L'implementazione per lo spostamento piegabile è FoldableNavHostFragment.
  • FoldableNavController : oggetto che gestisce lo spostamento dell'app all'interno di un oggetto FoldableNavHost.

Panoramica

Le applicazioni su dispositivi a doppio schermo e piegabili possono essere visualizzate su un singolo schermo o estese su una funzionalità di riduzione. Quando l'applicazione viene avviata per la prima volta:

  • In un solo frammento (A) sarà visibile.
  • Se viene eseguito il rendering dell'applicazione in una funzionalità di riduzione, il primo frammento (A) si troverà sul primo lato della piega e l'altro lato della piega sarà vuoto.

Dallo stato iniziale, se si passa a un altro frammento (B), il nuovo frammento verrà aperto nella schermata finale.

Se l'utente passa a un terzo frammento (C) verrà visualizzato nella schermata finale, il frammento precedente (B) verrà spostato nella schermata iniziale.

  • Quando l'app viene spostata dall'estensione a una singola schermata, tutti i frammenti dalla schermata finale vengono spostati nella schermata start e (C) verranno visualizzati in alto.
  • Quando l'app viene spostata da un singolo schermo a una cerniera o piegatura e lo stack di navigazione contiene più di due frammenti, l'ultimo frammento verrà spostato nella schermata finale.

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

Modificare la destinazione dell'area di visualizzazione per le azioni

È possibile specificare dove verrà visualizzato un nuovo frammento usando l'attributo launchScreen nel grafico di spostamento. I valori possibili per launchScreen sono:

  • start - il frammento verrà aperto nella prima schermata
  • end - il frammento verrà aperto nella seconda schermata
  • both - il frammento coprirà l'intera area di visualizzazione

In questo esempio XML di navigazione viene illustrato come usare questo attributo:

<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>

Importante

Questo attributo può essere modificato solo modificando direttamente il file XML. Non può essere modificato usando l'editor di Android Studio.

Esempio

È possibile scaricare questa app di esempio di spostamento per visualizzare tutti questi comportamenti.

Come importare la libreria nel progetto

  1. Aggiungere la dipendenza al file build.gradle a livello di modulo:

    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. Se il progetto viene creato con Java, sarà necessario aggiungere una dipendenza da kotlin-stdlib al file module-level build.gradle. Ciò è dovuto al fatto che alcune parti della libreria sono state create usando Kotlin.

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

Questi componenti sono basati sul componente Navigation fornito da Google e quindi la libreria di Foldable-Navigation contiene una dipendenza da tale componente.

Creare un grafico di spostamento

Un grafico di spostamento è un file di risorse xml con tutti i percorsi di spostamento dell'app, usando destinazioni e azioni. Il grafico di spostamento può essere creato tramite l'Editor di spostamento di Android Studio o manualmente tramite un editor XML. Per altre informazioni, vedere Creare un grafico di spostamento.

Aggiungere un NavHost a un'attività

Il componente di spostamento piegabile è progettato per le app con un'attività principale e più destinazioni di frammento. L'attività principale è associata a un grafico di navigazione e conterrà un oggetto FoldableNavHostFragment responsabile dello scambio di destinazioni di frammenti. Se l'app avrà più di un'attività, ogni attività avrà un proprio grafico di spostamento.

Questo è un file di layout XML dell'attività principale di esempio che illustra come impostare l'attributo app:navGraph :

<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>

Può FoldableNavHost anche essere impostato a livello di codice:

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

Per altre informazioni su come aggiungere a un'attività FoldableNavHost , vedere Aggiungere un NavHost a un'attività.

Questo frammento di codice può essere usato per esplorare i frammenti in base alle regole di spostamento piegabili:

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)
        }
    }
}

Aggiornare i componenti dell'interfaccia utente con FoldableNavigationUI

FoldableNavigationUI è un componente simile come NavigationUI nel componente Jetpack Navigation e contiene metodi statici che gestiscono lo spostamento con la barra dell'app superiore, il pannello di spostamento e lo spostamento inferiore. Per altre informazioni, vedere

FoldableNavigationUI contiene i metodi seguenti simili a quelli forniti da NavigationUI:

// 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)

Eseguire la migrazione di applicazioni esistenti alla navigazione piegabile

Le applicazioni esistenti che usano il componente Navigation fornito da Google possono aggiungere funzionalità pieghevoli seguendo questa procedura:

  1. Usare FoldableNavHostFragment invece di nella visualizzazione del contenitore di NavHostFragment frammenti modificando

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

    in

    <androidx.fragment.app.FragmentContainerView
         android:id="@+id/nav_host_fragment"
         android:name="androidx.navigation.FoldableNavHostFragment"
    
  2. Usare findFoldableNavController per ottenere l'istanza di FoldableNavController e usarla per spostarsi all'interno del grafico di spostamento modificando

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

    in

    findFoldableNavController().navigate(R.id.action_next)
    
  3. Usare FoldableNavigationUI invece di NavigationUI, modificando

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

    su

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