Crear un Navigation Drawer (menú lateral) en Android usando Kotlin


Apunte para implementar un menú lateral de navegación personalizado en su aplicación de Android, también conocido como (menú hamburguesa.

El Navigation Drawer es un panel que se expande y contrae desde un lado de la pantalla, muestra un menú de opciones a escoger el usuario, sirve para implementar un menú de navegación, para hacer aparecer el menú se puede pulsar sobre el icono de 3 líneas en la barra de herramientas superior o bien deslizando el dedo desde una esquina hacia dentro, para ocultar se puede tocar la zona oscura fuera de el, botón hacia atrás o bien seleccionando una opción del menú.

Prerrequisitos

Añadir siguiente dependencias en gradle.app

dependencies {
    // ...
    implementation 'com.google.android.material:material:1.2.1'
    // ...
 
}

Opcional: En el caso de querer que el menú aparezca por debajo de la barra de estado, se debe crear un tema propio para la Actividad que tendrá el menú de navegación.

<style name="AppTheme.DayNight.Transparent">
    <item name="windowActionBar">false</item>
    <item name="windowNoTitle">true</item>
    <item name="android:statusBarColor">@android:color/transparent</item>
</style>

recordar en establecer el tema en la activity en AndroidManifest.xml

<activity
    android:name=".MainActivity"
    android:label="@string/app_name"
    android:theme="@style/AppTheme.DayNight.Transparent"
    android:windowSoftInputMode="adjustPan">
    <intent-filter>
        <action android:name="android.intent.action.MAIN" />
        <category android:name="android.intent.category.LAUNCHER" />
    </intent-filter>
</activity>

Definiendo contenedor del menú lateral

Para definir el contenedor del menú lateral se usará el componente DrawerLayout

<?xml version="1.0" encoding="utf-8"?>
<androidx.drawerlayout.widget.DrawerLayout 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/drawer_layout"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:fitsSystemWindows="true"
    tools:openDrawer="start">

    <include
        layout="@layout/app_bar_main"
        android:layout_width="match_parent"
        android:layout_height="match_parent" />

    <com.google.android.material.navigation.NavigationView
        android:id="@+id/nav_view"
        android:layout_width="wrap_content"
        android:layout_height="match_parent"
        android:layout_gravity="start"
        android:fitsSystemWindows="true"
        app:headerLayout="@layout/nav_header_main"
        app:menu="@menu/activity_main_drawer" />


</androidx.drawerlayout.widget.DrawerLayout>

La propiedad android:fitsSystemWindows es donde se indica si queremos que el menú se dibuje por debajo de la barra de estado

A continuación se incrusta el layout que es donde habrá todos los elementos de la app que se muestran por debajo del menú lateral al expandirse.

El componente NavigationView es el encargado de dibujar las opciones del menú lateral,
con la propiedad app:headerLayout es donde se establece el layout de encabezado, normalmente una imagen y texto encima, con la propiedad app:menu podemos establecer el menú de opciones.

Añadir elementos al menú lateral

Ahora hace falta añadir los elementos a mostrar en el menú lateral, se definen como cualquier menu, en directorio, res/menu crear archivo activity_main_drawer.xml

<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    tools:showIn="navigation_view">

    <group android:checkableBehavior="single">
        <item
            android:id="@+id/nav_home"
            android:icon="@drawable/ic_dashboard_24"
            android:title="@string/menu_home" />
        <item
            android:id="@+id/nav_web_tools"
            android:icon="@drawable/ic_contacts_24"
            app:actionLayout="@layout/menu_counter"
            android:title="@string/menu_webtools" />
        <item
            android:id="@+id/nav_tools"
            android:icon="@drawable/ic_build_24"
            android:title="@string/menu_tools" />
    </group>

    <group
        android:id="@+id/third_section"
        android:checkableBehavior="none">
        <item
            android:id="@+id/nav_settings"
            android:icon="@drawable/ic_settings_24"
            android:title="@string/menu_settings" />
    </group>

</menu>

Inicialización del menú con Kotlin

Con todos los archivos de personalización a punto solo queda implementar la carga del menú lateral mediante código, en el MainActivity.kt sección onCreate()

override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)

    setContentView(R.layout.activity_main)
    setSupportActionBar(toolbar)
    supportActionBar?.setDisplayHomeAsUpEnabled(true)

    drawerLayout = findViewById(R.id.drawer_layout)
    val toggle = ActionBarDrawerToggle(
        this, drawerLayout, toolbar, R.string.navigation_drawer_open, R.string.navigation_drawer_close
    )
    drawerLayout.addDrawerListener(toggle)
    toggle.syncState()

    val navView: NavigationView = findViewById(R.id.nav_view)
    navView.setNavigationItemSelectedListener(this)

}  

en onBackPresed() es donde deberemos detectar si el menú está abierto lo debe cerrar y si está ya cerrado pues salga de la aplicación

override fun onBackPressed() {
    if (drawerLayout.isDrawerOpen(GravityCompat.START)) {
        drawerLayout.closeDrawer(GravityCompat.START)
    } else {
        super.onBackPressed()
    }
}

Para detectar que menú selecciona el usuario se hará con onNavigationItemSelected

override fun onNavigationItemSelected(item: MenuItem): Boolean {

    val id = item.itemId

    when (id) {
        R.id.nav_home, R.id.nav_web_tools, R.id.nav_tools -> {
            item.isChecked = true
                    }
        R.id.nav_settings -> startActivity(Intent(this, SettingsActivity::class.java))
    }

    return true

}

Recursos adicionales

Contenido de app_bar.xml

<?xml version="1.0" encoding="utf-8"?>
<androidx.coordinatorlayout.widget.CoordinatorLayout 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">

    <com.google.android.material.appbar.AppBarLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:theme="?attr/actionBarTheme">

        <androidx.appcompat.widget.Toolbar
            android:id="@+id/toolbar"
            android:layout_width="match_parent"
            android:layout_height="?attr/actionBarSize"
            android:background="?attr/colorPrimary"
            app:popupTheme="?attr/actionBarPopupTheme" />

    </com.google.android.material.appbar.AppBarLayout>

    <com.google.android.material.floatingactionbutton.FloatingActionButton
        android:id="@+id/fab"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_gravity="bottom|end"
        android:layout_margin="@dimen/fab_margin"
        app:backgroundTint="?attr/colorAccent"
        app:srcCompat="@drawable/ic_add_24" />

    <include layout="@layout/content_main" />

</androidx.coordinatorlayout.widget.CoordinatorLayout>

Contenido de content_main.xml

<?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"
    app:layout_behavior="@string/appbar_scrolling_view_behavior"
    tools:showIn="@layout/app_bar_main">

    <FrameLayout
        android:id="@+id/nav_host_fragment"
        android:name="androidx.navigation.fragment.NavHostFragment"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintRight_toRightOf="parent"
        app:layout_constraintTop_toTopOf="parent" />

</androidx.constraintlayout.widget.ConstraintLayout>
Anuncio publicitario

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: