Navigation Drawer

Por 9.99€ al mes tendrás acceso completo a todos los cursos. Sin matrícula ni permanencia.

Vamos a ver cómo puedes programar en Android un menú desplegable que entrará con una animación desde la parte izquierda de la pantalla.

Navigation Drawer toolbar en Android

Navigation Drawer en Android

Para que el código funcione, debemos importar las siguientes librerías en gradle:

implementation 'androidx.navigation:navigation-fragment:2.1.0'
implementation 'androidx.navigation:navigation-ui:2.1.0'
public class MyNavigationDrawer extends AppCompatActivity {

private AppBarConfiguration mAppBarConfiguration;

@Override
protected void onCreate(Bundle savedInstanceState) {
	super.onCreate(savedInstanceState);
	setContentView(R.layout.activity_main_navigation_drawer);
	//toolbar es la barra horizontal superior en la que se encuentra la hamburguesa con el menú de navegación
	Toolbar toolbar = findViewById(R.id.toolbar);
	setSupportActionBar(toolbar);

	// drawer es el layout del activity que contiene el Navigation Drawer y los activities con los que está vinculado
	DrawerLayout drawer = findViewById(R.id.drawer_layout);

	// navigationView es el menú Navigation Drawer
	NavigationView navigationView = findViewById(R.id.nav_view);

	// Debo pasar la id de cada menú al objeto de configuración del navigation drawer
	mAppBarConfiguration = new AppBarConfiguration.Builder(
			R.id.nav_home, R.id.nav_gallery, R.id.nav_slideshow,
			R.id.nav_tools, R.id.nav_share, R.id.nav_send)
			.setDrawerLayout(drawer)
			.build();

	//nav_host_fragment es la id del fragmento que alamcenará los activities de contenido
	NavController navController = Navigation.findNavController(this, R.id.nav_host_fragment);

	//vinculo el navController con su configuración
	NavigationUI.setupActionBarWithNavController(this, navController, mAppBarConfiguration);

	NavigationUI.setupWithNavController(navigationView, navController);
}

@Override
public boolean onSupportNavigateUp() {
	NavController navController = Navigation.findNavController(this, R.id.nav_host_fragment);
	return NavigationUI.navigateUp(navController, mAppBarConfiguration)
			|| super.onSupportNavigateUp();
}
}

Cargamos un activity que tendrá un layout que cargará dos componentes:

  • El layout en el que se cargarán los fragments.
  • El menú de navegación.
activity_main_navigation_drawer.xml
<?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">

	<!-- En este componente cargaremos el contenido -->
	<include
		layout="@layout/app_bar_main"
		android:layout_width="match_parent"
		android:layout_height="match_parent" />

	<!-- Este componente es el menú de navegación -->
	<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>

Este es el xml del documento en el que se cargarán los datos:

res/layouts/app_bar_main.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="@style/AppTheme.AppBarOverlay">

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

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

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

</androidx.coordinatorlayout.widget.CoordinatorLayout>

Este xml carga otro xml que es el que finalmente cargará los contenidos.

res/layouts/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">

    <fragment
        android:id="@+id/nav_host_fragment"
        android:name="androidx.navigation.fragment.NavHostFragment"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        app:defaultNavHost="true"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintRight_toRightOf="parent"
        app:layout_constraintTop_toTopOf="parent"
        app:navGraph="@navigation/mobile_navigation" />
</androidx.constraintlayout.widget.ConstraintLayout>

Finalmente, el xml de los contenidos:

navigation/mobile_navigation.xml
<?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/mobile_navigation"
    app:startDestination="@+id/nav_home">

    <fragment
        android:id="@+id/nav_home"
        android:name="com.pablomonteserin.layouts.minavigationdrawer.ui.home.HomeFragment"
        android:label="@string/menu_home"
        tools:layout="@layout/fragment_home" />

    <fragment
        android:id="@+id/nav_gallery"
        android:name="com.pablomonteserin.layouts.minavigationdrawer.ui.gallery.GalleryFragment"
        android:label="@string/menu_gallery"
        tools:layout="@layout/fragment_gallery" />

    <fragment
        android:id="@+id/nav_slideshow"
        android:name="com.pablomonteserin.layouts.minavigationdrawer.ui.slideshow.SlideshowFragment"
        android:label="@string/menu_slideshow"
        tools:layout="@layout/fragment_slideshow" />

    <fragment
        android:id="@+id/nav_tools"
        android:name="com.pablomonteserin.layouts.minavigationdrawer.ui.tools.ToolsFragment"
        android:label="@string/menu_tools"
        tools:layout="@layout/fragment_tools" />

    <fragment
        android:id="@+id/nav_share"
        android:name="com.pablomonteserin.layouts.minavigationdrawer.ui.share.ShareFragment"
        android:label="@string/menu_share"
        tools:layout="@layout/fragment_share" />

    <fragment
        android:id="@+id/nav_send"
        android:name="com.pablomonteserin.layouts.minavigationdrawer.ui.send.SendFragment"
        android:label="@string/menu_send"
        tools:layout="@layout/fragment_send" />
</navigation>
HomeFragment.java
public class HomeFragment extends Fragment {
	public View onCreateView(@NonNull LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
	View root = inflater.inflate(R.layout.fragment_home, container, false);
	final TextView textView = root.findViewById(R.id.text_home);
	return root;
}
}

Y el menú de navegación:

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"
    tools:showIn="navigation_view">

    <group android:checkableBehavior="single">
        <item
            android:id="@+id/nav_home"
            android:icon="@drawable/ic_menu_camera"
            android:title="@string/menu_home" />
        <item
            android:id="@+id/nav_gallery"
            android:icon="@drawable/ic_menu_gallery"
            android:title="@string/menu_gallery" />
        <item
            android:id="@+id/nav_slideshow"
            android:icon="@drawable/ic_menu_slideshow"
            android:title="@string/menu_slideshow" />
        <item
            android:id="@+id/nav_tools"
            android:icon="@drawable/ic_menu_manage"
            android:title="@string/menu_tools" />
    </group>

    <item android:title="Communicate">
        <menu>
            <item
                android:id="@+id/nav_share"
                android:icon="@drawable/ic_menu_share"
                android:title="@string/menu_share" />
            <item
                android:id="@+id/nav_send"
                android:icon="@drawable/ic_menu_send"
                android:title="@string/menu_send" />
        </menu>
    </item>

</menu>
res/values/style.xml
<resources>
	<style name="AppTheme.NoActionBar">
		<item name="windowActionBar">false</item>
		<item name="windowNoTitle">true</item>
	</style>
	<style name="AppTheme.AppBarOverlay" parent="ThemeOverlay.AppCompat.Dark.ActionBar" />
	<style name="AppTheme.PopupOverlay" parent="ThemeOverlay.AppCompat.Light" />
</resources>

Por 9.99€ al mes tendrás acceso completo a todos los cursos. Sin matrícula ni permanencia.