Cómo navegar con opciones

Cuando defines una acción en el gráfico de navegación con la DSL de Kotlin, Navigation genera una clase NavAction correspondiente, que contiene las configuraciones definidas para esa acción, incluidas las siguientes:

  • Destino: Es el ID de recurso del destino objetivo.
  • Argumentos predeterminados: Es un objeto android.os.Bundle que contiene valores predeterminados para el destino objetivo (si se lo suministró).
  • Opciones de navegación: Son las opciones de Navigation, representadas como NavOptions. Esta clase contiene toda la configuración especial para la transición hacia el destino objetivo y desde él, lo que incluye la configuración del recurso de animación, el comportamiento emergente y si el destino debería lanzarse en un solo modo superior.

Opciones con Compose

De forma predeterminada, navigate() agrega el nuevo destino a la pila de actividades. Puedes modificar el comportamiento de navigate() pasando opciones de navegación adicionales a tu llamada a navigate().

Puedes crear una instancia de NavOptions con una lambda simple. Pasa a navigate() los argumentos que, de otro modo, podrías pasar de forma explícita a NavOptions.Builder. Considera los siguientes ejemplos:

Si quieres ver ejemplos, consulta la guía de pila de actividades para ver cómo pasar opciones a navigate() en contexto.

Opciones con XML

El siguiente es un ejemplo de gráfico que consta de dos pantallas junto con una acción para navegar de una a la otra:

<?xml version="1.0" encoding="utf-8"?>
<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/nav_graph"
            app:startDestination="@id/a">

    <fragment android:id="@+id/a"
              android:name="com.example.myapplication.FragmentA"
              android:label="a"
              tools:layout="@layout/a">
        <action android:id="@+id/action_a_to_b"
                app:destination="@id/b"
                app:enterAnim="@anim/nav_default_enter_anim"
                app:exitAnim="@anim/nav_default_exit_anim"
                app:popEnterAnim="@anim/nav_default_pop_enter_anim"
                app:popExitAnim="@anim/nav_default_pop_exit_anim"/>
    </fragment>

    <fragment android:id="@+id/b"
              android:name="com.example.myapplication.FragmentB"
              android:label="b"
              tools:layout="@layout/b">
        <action android:id="@+id/action_b_to_a"
                app:destination="@id/a"
                app:enterAnim="@anim/nav_default_enter_anim"
                app:exitAnim="@anim/nav_default_exit_anim"
                app:popEnterAnim="@anim/nav_default_pop_enter_anim"
                app:popExitAnim="@anim/nav_default_pop_exit_anim"
                app:popUpTo="@+id/a"
                app:popUpToInclusive="true"/>
    </fragment>
</navigation>

Cuando aumenta el gráfico de navegación, se analizan esas acciones y se generan los objetos NavAction correspondientes con las configuraciones definidas en el gráfico. Por ejemplo, se define action_b_to_a como la navegación desde el destino b hacia el destino a. La acción incluye animaciones, además del comportamiento popTo, que quita todos los destinos de la pila de actividades. Todas esas configuraciones se capturan como NavOptions y se adjuntan al NavAction.

Para seguir esta NavAction, usa NavController.navigate() y pasa el ID de la acción, como se muestra en el siguiente ejemplo:

    navController.navigate(R.id.action_b_to_a)

Aplica opciones de manera programática

En los ejemplos anteriores, se muestra cómo especificar NavOptions en el archivo XML del gráfico de navegación. Sin embargo, las opciones específicas pueden variar según las restricciones que se desconozcan durante el tiempo de compilación. En esos casos, NavOptions se debe crear y configurar de manera programática, como se muestra en el siguiente ejemplo:

Kotlin

findNavController().navigate(
R.id.action_fragmentOne_to_fragmentTwo,
null,
navOptions { // Use the Kotlin DSL for building NavOptions
    anim {
        enter = android.R.animator.fade_in
        exit = android.R.animator.fade_out
    }
  }
)

Java

NavController navController = NavHostFragment.findNavController(this);
  navController.navigate(
    R.id.action_fragmentOne_to_fragmentTwo,
    null,
    new NavOptions.Builder()
      .setEnterAnim(android.R.animator.fade_in)
      .setExitAnim(android.R.animator.fade_out)
      .build()
  );

En este ejemplo, se usa una forma extendida de navigate() y se incluyen argumentos adicionales de Bundle y NavOptions. Todas las variantes de navigate() tienen versiones extendidas que aceptan un argumento de NavOptions.

También puedes aplicar NavOptions de manera programática cuando navegas a vínculos directos implícitos:

Kotlin

findNavController().navigate(
    deepLinkUri,
    navOptions { // Use the Kotlin DSL for building NavOptions
        anim {
            enter = android.R.animator.fade_in
            exit = android.R.animator.fade_out
        }
    }
)

Java

NavController navController = NavHostFragment.findNavController(this);
navController.navigate(
        deepLinkUri,
        new NavOptions.Builder()
                .setEnterAnim(android.R.animator.fade_in)
                .setExitAnim(android.R.animator.fade_out)
                .build()
);

Esta variante de navigate() toma un Uri para el vínculo directo implícito y para la instancia de NavOptions.