Implementación de Navigation Controller Jetpack Kotlin


Dentro del conjunto de componente de arquitectura de android (Jetpack) encontramos el componente Navigation Controller, que sirve para implementar la navegación entre vistas de la app, facilitando el proceso de carga de fragmentos y control de ir atrás.

Documentación oficial Get started with the Navigation Component

Dependencias

Dependencias del componente Navigation Controller, agregar la siguientes dependencias en app.gradle

implementation 'androidx.navigation:navigation-fragment-ktx:2.0.0'
implementation 'androidx.navigation:navigation-ui-ktx:2.0.0'

//Add support java 1.8 and Kotlin for AppBarConfiguration
    compileOptions {
        sourceCompatibility JavaVersion.VERSION_1_8
        targetCompatibility JavaVersion.VERSION_1_8
    }
    kotlinOptions {
        jvmTarget = "1.8"
    }

Prerequisitos para el componente Navigation

Para usar el componente navigation se debe especificar el sistema de navegación y su enclave maestro pa

Crea un gráfico de navegación

El paso siguiente es establecer el sistema de navegación principal, para eso debemos crear un nuevo recurso de tipo navigation

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

  • En la ventana Proyecto, haga clic derecho en el directorio res y Menú contextual seleccione New resource file para que aparezca el cuadro de dialogo New Resource File
  • Establecer el nombre del archivo nav_graph
  • Seleccionar el tipo navigation en la lista desplegable
  • Pulse OK

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

Crear enclave maestro para la navegación

El host de navegación es un contenedor vacío donde los destinos se intercambian dentro y fuera mientras el usuario navega por su aplicación.

En el layout que queremos que tenga el sistema de navegación principal añadir:

    <androidx.fragment.app.FragmentContainerView
        android:id="@+id/fragment_container"
        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" />

Agregando destinos

Para agregar destinos de navegación, se hace desde editor de navegación, solo es necesario ir poniendo los fragmentos o actividades

Recuerda en establecer un fragmento como principal

Añadir elementos de navegación

Si queremos visualizar los elementos de navegación en la barra de estado

val host: NavHostFragment = supportFragmentManager.findFragmentById(R.id.nav_host_fragment) as NavHostFragment? ?: return
        val navController = host.navController

 val appBarConfiguration = AppBarConfiguration(navController.graph)

NavigationUI.setupWithNavController(toolbar, navController, appBarConfiguration)

Cambiar el titulo de la toolbar

Cuando se inicie un fragment y queremos cambiar el titulo des de el fragment, en el evento onCreatedView de cada Fragment añadir

(activity as AppCompatActivity).supportActionBar?.title = "titulo a cambiar"

Errores comunes

Errores más comunes al usar el componente Navigation Controller

Al navegar a un destino que es el actual, la segunda vez que se navega a un destino en su mismo destino se puede recibir

java.lang.IllegalArgumentException: navigation destination com.webserveis.testnavigationcomponent:id/action_oneFragment_to_twoFragment is unknown to this NavController

Para solucionar eso, se debe comprobar que destino nos encontramos y si coincide el destino sea el origen, no permite navegar

if (navController.currentDestination?.id == R.id.fragmentA) {
    navController.navigate(R.id.action_fragmentA_to_fragmentB)
}

Recursos

override fun onBackPressed() = when {
    navController.graph.startDestination == navController.currentDestination?.id -> showQuitDialog()
    else -> super.onBackPressed()
}

fun NavController.navigateSafe(
        @IdRes resId: Int,
        args: Bundle? = null,
        navOptions: NavOptions? = null,
        navExtras: Navigator.Extras? = null
) {
    val action = currentDestination?.getAction(resId) ?: graph.getAction(resId)
    if (action != null && currentDestination?.id != action.destinationId) {
        navigate(resId, args, navOptions, navExtras)
    }
}

Puedes ver y seguir los pasos en el siguiente vídeo

Recursos

Código de ejemplo de implementación del Component Navigation, Mi Google Drive

Publicado por Codelaby

Mobile DevDesigner

Deja una respuesta

Introduce tus datos o haz clic en un icono para iniciar sesión:

Logo de WordPress.com

Estás comentando usando tu cuenta de WordPress.com. Salir /  Cambiar )

Imagen de Twitter

Estás comentando usando tu cuenta de Twitter. Salir /  Cambiar )

Foto de Facebook

Estás comentando usando tu cuenta de Facebook. Salir /  Cambiar )

Conectando a %s

Este sitio usa Akismet para reducir el spam. Aprende cómo se procesan los datos de tus comentarios.

A %d blogueros les gusta esto: