Cómo comenzar a usar el componente Navigation

En esta sección, se muestra cómo configurar el componente Navigation y cómo trabajar con él. Si deseas obtener una descripción general de nivel superior del componente Navigation, consulta la descripción general de Navigation.

Desarrolla tu entorno

Para incluir compatibilidad con Navigation en tu proyecto, agrega las siguientes dependencias al archivo build.gradle de tu app:

Groovy

dependencies {
  def nav_version = "2.7.5"

  // Java language implementation
  implementation "androidx.navigation:navigation-fragment:$nav_version"
  implementation "androidx.navigation:navigation-ui:$nav_version"

  // Kotlin
  implementation "androidx.navigation:navigation-fragment-ktx:$nav_version"
  implementation "androidx.navigation:navigation-ui-ktx:$nav_version"

  // Feature module Support
  implementation "androidx.navigation:navigation-dynamic-features-fragment:$nav_version"

  // Testing Navigation
  androidTestImplementation "androidx.navigation:navigation-testing:$nav_version"

  // Jetpack Compose Integration
  implementation "androidx.navigation:navigation-compose:$nav_version"
}

Kotlin

dependencies {
  val nav_version = "2.7.5"

  // Java language implementation
  implementation("androidx.navigation:navigation-fragment:$nav_version")
  implementation("androidx.navigation:navigation-ui:$nav_version")

  // Kotlin
  implementation("androidx.navigation:navigation-fragment-ktx:$nav_version")
  implementation("androidx.navigation:navigation-ui-ktx:$nav_version")

  // Feature module Support
  implementation("androidx.navigation:navigation-dynamic-features-fragment:$nav_version")

  // Testing Navigation
  androidTestImplementation("androidx.navigation:navigation-testing:$nav_version")

  // Jetpack Compose Integration
  implementation("androidx.navigation:navigation-compose:$nav_version")
}

Si quieres obtener información para agregar otros componentes de la arquitectura a tu proyecto, consulta la sección Cómo agregar componentes a tu proyecto.

Cómo crear un gráfico de navegación

La navegación ocurre entre los destinos de tu app, es decir, en cualquier lugar de tu app en el que los usuarios puedan navegar. Estos destinos están conectados a través de acciones.

Un gráfico de navegación es un archivo de recursos que contiene todos tus destinos y acciones. El gráfico representa todas las rutas de navegación de tu app.

En la figura 1, se muestra una representación visual de un gráfico de navegación para una app de muestra, que contiene seis destinos conectados por cinco acciones. Cada destino se representa con una miniatura de vista previa, mientras que las acciones de conexión se representan a través de flechas que muestran cómo los usuarios pueden navegar de un destino al otro.

Figura 1: Gráfico de navegación en el que se muestran vistas previas de seis destinos diferentes conectados a través de cinco acciones
  1. Los destinos son las diferentes áreas de contenido en tu app.
  2. Las acciones son conexiones lógicas entre tus destinos que representan las rutas que los usuarios pueden seguir.

Para agregar un gráfico de navegación a tu proyecto, haz lo siguiente:

  1. En la ventana Project, haz clic con el botón derecho en el directorio de res y selecciona New > Android Resource File. Se muestra el diálogo New Resource File.
  2. Escribe un nombre como "nav_graph" en el campo File name.
  3. Selecciona Navigation en la lista desplegable Resource type y, luego, haz clic en OK.

Cuando agregas tu primer gráfico de navegación, Android Studio crea un directorio de recursos de navigation dentro del directorio de res. Este directorio contiene tu archivo de recursos del gráfico de navegación (por ejemplo, nav_graph.xml).

Después de agregar un gráfico, Android Studio abre el gráfico en el Editor de Navigation. En el Editor de Navigation, puedes editar a nivel visual los gráficos de navegación o editar directamente el XML subyacente.

Figura 2: Editor de Navigation
  1. Panel de destinos: muestra una lista de tu host de navegación y todos los destinos que se encuentran actualmente en el Graph Editor.
  2. Graph Editor: incluye una representación visual de tu gráfico de navegación. Puedes cambiar entre la vista Design y la representación del XML subyacente en la vista Text.
  3. Atributos: muestra atributos del elemento seleccionado actualmente en el gráfico de navegación.

Haz clic en la pestaña Text para ver el XML correspondiente, que debería ser similar al siguiente fragmento:

<?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"
            android:id="@+id/nav_graph">

</navigation>

<navigation> es el elemento raíz de un gráfico de navegación. A medida que agregas destinos y conectas acciones a tu gráfico, puedes ver los elementos correspondientes <destination> y <action> como secundarios. Si tienes gráficos anidados, se muestran como elementos <navigation> secundarios.

Cómo agregar un NavHost a una actividad

Una de las partes principales del componente Navigation es el host de navegación. El host de navegación es un contenedor vacío en el que se intercambian los destinos a medida que un usuario navega por tu app.

Un host de navegación debe derivar de NavHost. La implementación predeterminada de NavHost del componente Navigation, NavHostFragment, se encarga de intercambiar los destinos de fragmentos.

Cómo agregar un NavHostFragment a través de XML

En el siguiente ejemplo de XML, se muestra un NavHostFragment como parte de la actividad principal de una app.

<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout
    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:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".MainActivity">

    <androidx.appcompat.widget.Toolbar
        .../>

    <androidx.fragment.app.FragmentContainerView
        android:id="@+id/nav_host_fragment"
        android:name="androidx.navigation.fragment.NavHostFragment"
        android:layout_width="0dp"
        android:layout_height="0dp"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintRight_toRightOf="parent"
        app:layout_constraintTop_toTopOf="parent"
        app:layout_constraintBottom_toBottomOf="parent"

        app:defaultNavHost="true"
        app:navGraph="@navigation/nav_graph" />

    <com.google.android.material.bottomnavigation.BottomNavigationView
        .../>

</androidx.constraintlayout.widget.ConstraintLayout>

Ten en cuenta lo siguiente:

  • El atributo android:name contiene el nombre de clase de tu implementación de NavHost.
  • El atributo app:navGraph asocia el NavHostFragment con un gráfico de navegación. En el gráfico de navegación, se especifican todos los destinos a los que el usuario puede navegar en este NavHostFragment.
  • El atributo app:defaultNavHost="true" garantiza que tu NavHostFragment intercepte el botón Atrás del sistema. Ten en cuenta que solo un NavHost puede ser el valor predeterminado. Si tienes varios hosts en el mismo diseño (diseños de dos paneles, por ejemplo), asegúrate de especificar solo un NavHost predeterminado.

También puedes usar el editor de diseño a fin de agregar un NavHostFragment a una actividad. Para ello, haz lo siguiente:

  1. En la lista de archivos de tu proyecto, haz doble clic en el archivo de diseño en formato XML de tu actividad para abrirlo en el editor de diseño.
  2. En el panel Palette, selecciona la categoría Containers o busca "NavHostFragment".
  3. Arrastra la vista de NavHostFragment a tu actividad.
  4. Luego, en el diálogo Navigation Graphs que se muestra, elige el gráfico de navegación correspondiente para asociarlo con este NavHostFragment y, luego, haz clic en OK.

Cómo agregar destinos al gráfico de navegación

Puedes crear un destino a partir de un fragmento o una actividad existente. También puedes usar el Editor de Navigation para crear un destino nuevo o un marcador de posición y reemplazarlo con un fragmento o una actividad posteriormente.

En este ejemplo, crearemos un destino nuevo. Para agregar un destino nuevo mediante el Editor de Navigation, haz lo siguiente:

  1. En el Editor de Navigation, haz clic en el ícono New Destination y, luego, en Create new destination.
  2. Crea tu fragmento en el diálogo New Android Component que se muestra. Si deseas obtener más información sobre los fragmentos, consulta la documentación correspondiente.

En el Editor de Navigation, verás que Android Studio agregó este destino al gráfico.

En la Figura 3, se muestra un ejemplo de un destino y un destino de marcador de posición.

Figura 3: Un destino y un marcador de posición

Si deseas conocer otras maneras de agregar destinos a tu gráfico de navegación, consulta Cómo crear destinos.

Anatomía de un destino

Haz clic en un destino para seleccionarlo y observa los siguientes atributos en el panel Attributes:

  • El campo Type indica si un destino se implementa como un fragmento, una actividad o cualquier otra clase personalizada en tu código fuente.
  • El campo Label contiene el nombre del destino legible para el usuario. Esto podría aparecer en la IU, por ejemplo, si conectas el NavGraph a la Toolbar usandosetupWithNavController(). Por este motivo, se recomienda que uses strings de recursos para este valor.
  • El campo ID contiene el ID del destino que se utiliza para hacer referencia al destino en el código.
  • En el menú desplegable Class, se muestra el nombre de la clase que está asociada con el destino. Puedes hacer clic en este menú desplegable para cambiar la clase asociada por otro tipo de destino.

Haz clic en la pestaña Text para mostrar la vista XML de tu gráfico de navegación. El archivo en formato XML contiene los mismos atributos id, name, label y layout para el destino, como se muestra a continuación:

<?xml version="1.0" encoding="utf-8"?>
<navigation xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    xmlns:android="http://schemas.android.com/apk/res/android"
    app:startDestination="@id/blankFragment">
    <fragment
        android:id="@+id/blankFragment"
        android:name="com.example.cashdog.cashdog.BlankFragment"
        android:label="@string/label_blank"
        tools:layout="@layout/fragment_blank" />
</navigation>

Cómo designar una pantalla como destino de inicio

El destino de inicio es la primera y la última pantalla que ven los usuarios cuando abren y cierran tu app, respectivamente. El Editor de Navigation usa el ícono de una casa para indicar el destino de inicio.

Una vez que todos tus destinos estén en su lugar, puedes elegir un destino de inicio de la siguiente manera:

  1. En la pestaña Design, haz clic en el destino para destacarlo.

  2. Haz clic en el botón Assign start destination . También puedes hacer clic con el botón derecho en el destino y seleccionar Set as Start Destination.

Cómo conectar destinos

Una acción es una conexión lógica entre destinos. Las acciones se representan en el gráfico de navegación como flechas. Por lo general, las acciones conectan un destino con el otro, aunque también puedes crear acciones generales que dirijan a un destino específico desde cualquier lugar de tu app.

Mediante acciones, representas las diferentes rutas que los usuarios pueden seguir en tu app. Ten en cuenta que para realmente navegar a los destinos, debes escribir código que realice la navegación. Este tema se trata en la sección Cómo navegar a un destino más adelante.

Puedes usar el Editor de Navigation para conectar dos destinos de la siguiente manera:

  1. En la pestaña Design, coloca el cursor sobre el lado derecho del destino desde el que quieres que naveguen los usuarios. Aparecerá un círculo sobre el lado derecho del destino, como se muestra en la figura 4.

    Figura 4: Un destino con un círculo de conexión de acción
  2. Haz clic y arrastra el cursor sobre el destino al que quieres que los usuarios naveguen y suéltalo. La línea resultante entre los dos destinos representa una acción, como se muestra en la figura 5.

    Figura 5: Cómo conectar destinos con una acción
  3. Haz clic en la flecha para destacar la acción. Los siguientes atributos se muestran en el panel Attributes:

    • El campo Type contiene "Action".
    • El campo ID contiene el ID de la acción.
    • El campo Destination contiene el ID del fragmento o la actividad del destino.
  4. Haz clic en la pestaña Text para activar la vista XML. Ahora se agrega un elemento de acción al destino de origen. La acción tiene un ID y un atributo de destino que contiene el ID del próximo destino, como se muestra en el siguiente ejemplo:

    <?xml version="1.0" encoding="utf-8"?>
    <navigation xmlns:app="http://schemas.android.com/apk/res-auto"
        xmlns:tools="http://schemas.android.com/tools"
        xmlns:android="http://schemas.android.com/apk/res/android"
        app:startDestination="@id/blankFragment">
        <fragment
            android:id="@+id/blankFragment"
            android:name="com.example.cashdog.cashdog.BlankFragment"
            android:label="@string/label_blank"
            tools:layout="@layout/fragment_blank" >
            <action
                android:id="@+id/action_blankFragment_to_blankFragment2"
                app:destination="@id/blankFragment2" />
        </fragment>
        <fragment
            android:id="@+id/blankFragment2"
            android:name="com.example.cashdog.cashdog.BlankFragment2"
            android:label="@string/label_blank_2"
            tools:layout="@layout/fragment_blank_fragment2" />
    </navigation>
    

En tu gráfico de navegación, las acciones se representan con elementos <action>. Como mínimo, una acción contiene su propio ID y el ID del destino al que se debería dirigir a un usuario.

La navegación a un destino se realiza con un NavController, un objeto que administra la navegación de una app dentro de un elemento NavHost. Cada NavHost tiene su propio NavController correspondiente. Para recuperar un NavController, puedes usar uno de los siguientes métodos:

Kotlin:

Java:

Cuando crees el NavHostFragment con FragmentContainerView o si agregas manualmente NavHostFragment a tu actividad a través de una FragmentTransaction, intenta recuperar el NavController en onCreate() de una actividad a través de Navigation.findNavController(Activity, @IdRes int). En su lugar, debes recuperar la NavController directamente del NavHostFragment.

Kotlin

val navHostFragment =
        supportFragmentManager.findFragmentById(R.id.nav_host_fragment) as NavHostFragment
val navController = navHostFragment.navController

Java

NavHostFragment navHostFragment =
        (NavHostFragment) getSupportFragmentManager().findFragmentById(R.id.nav_host_fragment);
NavController navController = navHostFragment.getNavController();

Cómo garantizar la seguridad de tipo mediante Safe Args

Para navegar entre destinos, te recomendamos que uses el complemento de Gradle Safe Args, Este complemento genera clases de objetos y compiladores simples que permiten navegar con seguridad de tipo y pasar argumentos entre destinos.

Para agregar Safe Args a tu proyecto, incluye la siguiente classpath en tu archivo build.gradle de nivel superior:

Groovy

buildscript {
    repositories {
        google()
    }
    dependencies {
        def nav_version = "2.5.3"
        classpath "androidx.navigation:navigation-safe-args-gradle-plugin:$nav_version"
    }
}

Kotlin

buildscript {
    repositories {
        google()
    }
    dependencies {
        val nav_version = "2.5.3"
        classpath("androidx.navigation:navigation-safe-args-gradle-plugin:$nav_version")
    }
}

También debes aplicar uno de los dos complementos disponibles.

Para generar código de lenguaje Java adecuado para Java o módulos combinados de Java y Kotlin, agrega esta línea al archivo build.gradle de tu app o módulo:

Groovy

plugins {
  id 'androidx.navigation.safeargs'
}

Kotlin

plugins {
    id("androidx.navigation.safeargs")
}

Como alternativa, para generar el código de Kotlin adecuado para módulos solo de Kotlin, agrega lo siguiente:

Groovy

plugins {
  id 'androidx.navigation.safeargs.kotlin'
}

Kotlin

plugins {
    id("androidx.navigation.safeargs.kotlin")
}

Tienes que tener el objeto android.useAndroidX=true en tu archivo gradle.properties, según se indica en Cómo migrar a AndroidX.

Después de habilitar Safe Args, el complemento genera código que contiene clases y métodos para cada acción que definiste. En cada acción, Safe Args también genera una clase para cada destino de origen, que es el destino desde el que se origina la acción. El nombre de clase generado es una combinación del nombre de clase del destino de origen y la palabra "Directions". Por ejemplo, si el destino se llama SpecifyAmountFragment, la clase generada se llama SpecifyAmountFragmentDirections. La clase generada contiene un método estático para cada acción definida en el destino de origen. Este método toma cualquier parámetro de acción definido como argumento y muestra un objeto NavDirections que puedes pasar a navigate().

Como ejemplo, imagina que tienes un gráfico de navegación con una sola acción que conecta el destino de origen, SpecifyAmountFragment, con un destino de recepción, ConfirmationFragment.

Safe Args genera una clase SpecifyAmountFragmentDirections con un solo método, actionSpecifyAmountFragmentToConfirmationFragment() que muestra un objeto NavDirections. Luego, puedes pasar este objeto NavDirections que se mostró directamente a navigate(), como se indica en el siguiente ejemplo:

Kotlin

override fun onClick(view: View) {
    val action =
        SpecifyAmountFragmentDirections
            .actionSpecifyAmountFragmentToConfirmationFragment()
    view.findNavController().navigate(action)
}

Java

@Override
public void onClick(View view) {
    NavDirections action =
        SpecifyAmountFragmentDirections
            .actionSpecifyAmountFragmentToConfirmationFragment();
    Navigation.findNavController(view).navigate(action);
}

Si quieres obtener más información para pasar datos entre destinos con Safe Args, consulta Cómo usar Safe Args para pasar datos con seguridad de tipo.

Más información

Si tienes problemas con Navigation, envía comentarios a través de uno de los siguientes canales:

Para descubrir cómo proporcionar la información más útil en los informes de errores, consulta los siguientes vínculos: