Android Navigation Drawer like Gmail with Fragment

Achmad Qomarudin
5 min readNov 29, 2019

Navigation Drawer is a component that slide right from the left of the screen having multiple options. Here are the examples of the Navigation Drawer from apps.

There are three types of navigation drawer, Standard Drawer, Modal Drawer and Bottom Drawer.

Standard Drawer: Standard navigation drawers allow users to simultaneously access drawer destinations and app content. They are often co-planar with app content and affect the screen’s layout grid.

Standard drawers can be permanently visible or opened and closed by tapping a navigation menu icon. They can be used on tablet and desktop only. On mobile, modal drawers are used instead.

Standard Drawer

Modal Drawer: Modal navigation drawers use a scrim to block interaction with the rest of an app’s content. They are elevated above most app elements and don’t affect the screen’s layout grid.

They are primarily for use on mobile, where screen space is limited. They can be replaced by standard drawers on tablet and desktop.

Modal Drawer

Bottom Drawer: Bottom navigation drawers are a specialized type of modal drawer for use with a bottom app bar.

For increased reachability from the bottom app bar’s menu icon, they open from the bottom of the screen rather than the side.

Ok, now let’s start to implement the first modal drawer.

After creating a new project, open build.gradle file in app level, add support design dependency because the navigation drawer is the component of android material library, and don’t forget to add library circle image for rounded image.

//for component navigation drawer
implementation 'com.google.android.material:material:1.0.0'
//for rounded image
implementation 'de.hdodenhof:circleimageview:3.0.1'

Create app_bar_main.xml layout:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:fitsSystemWindows="true">

<com.google.android.material.appbar.AppBarLayout
android:id="@+id/action_bar"
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="@color/colorLightRed"
app:popupTheme="@style/AppTheme.PopupOverlay" />

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

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

Create content_main.xml layout:

<?xml version="1.0" encoding="utf-8"?>
<FrameLayout 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/content_frame"
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>

Create nav_header_main.xml layout:

<RelativeLayout 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"
android:id="@+id/container"
android:layout_width="match_parent"
android:layout_height="180dp">

<LinearLayout
android:layout_width="match_parent"
android:layout_height="180dp"
android:gravity="bottom"
android:background="@color/colorLightRed"
android:paddingStart="16dp"
android:orientation="vertical"
tools:ignore="RtlSymmetry">

<de.hdodenhof.circleimageview.CircleImageView
android:id="@+id/imageView"
android:layout_width="100dp"
android:layout_height="100dp"
app:civ_border_color="@android:color/white"
app:civ_border_width="3dp"
android:src="@drawable/ic_profile_default" />

<TextView
android:id="@+id/atv_name_header"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Budi"
android:textColor="@android:color/white"
android:layout_marginTop="5dp"
android:textStyle="bold"
android:textSize="15sp" />

<TextView
android:id="@+id/tv_email_header"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textColor="@android:color/white"
android:paddingBottom="5dp"
android:textSize="12sp"
android:text="budi@gmail.com" />

</LinearLayout>
</RelativeLayout>

Create directory menu inside directory res, and then create menu_nav_drawer.xml layout:

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

<group
android:id="@+id/menu_top"
android:checkableBehavior="single">

<item
android:id="@+id/menu_home"
app:actionViewClass="android.widget.TextView"
android:icon="@drawable/ic_home"
android:title="Home" />

<item
android:id="@+id/menu_pengurus"
app:actionViewClass="android.widget.TextView"
android:icon="@drawable/ic_pengurus"
android:title="Pengurus" />

</group>

<group
android:id="@+id/menu_bottom"
android:checkableBehavior="single">

<item
android:id="@+id/menu_saran_dan_kritikan"
app:actionViewClass="android.widget.TextView"
android:icon="@drawable/ic_saran"
android:title="Saran Dan Kritikan" />
<item
android:id="@+id/menu_about"
app:actionViewClass="android.widget.TextView"
android:icon="@drawable/ic_about"
android:title="About" />
<item
android:id="@+id/menu_logout"
app:actionViewClass="android.widget.TextView"
android:icon="@drawable/ic_logout"
android:title="Logout" />
</group>
</menu>

Now insert this code to activity_main.xml layout:

<?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:itemBackground="@drawable/drawer_selected_item"
app:headerLayout="@layout/nav_header_main"
app:menu="@menu/menu_nav_drawer" />

</androidx.drawerlayout.widget.DrawerLayout>

Now, insert this code to class MainActivity.java :

public class MainActivity extends AppCompatActivity implements NavigationView.OnNavigationItemSelectedListener {

public Toolbar toolbar;
private MenuItem menuHome, menuPengurus, menuSaranDanKritikan, menuAbout, menuLogout;
boolean doubleBackToExitPressedOnce = false;

public MainActivity() {
}

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);

toolbar = findViewById(R.id.toolbar);
setSupportActionBar(toolbar);

loadFragment(new HomeFragment());

NavigationView navigationView = findViewById(R.id.nav_view);
navigationView.setNavigationItemSelectedListener(this);
navigationView.setItemIconTintList(null); //disable tint on each icon to use color icon svg

DrawerLayout drawer = findViewById(R.id.drawer_layout);
ActionBarDrawerToggle toggle = new ActionBarDrawerToggle(
this, drawer, toolbar, R.string.navigation_drawer_open, R.string.navigation_drawer_close);
drawer.setDrawerListener(toggle);
toggle.syncState();

//custom header view
View headerView = navigationView.getHeaderView(0);
RelativeLayout container = headerView.findViewById(R.id.container);
container.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
startActivity(new Intent(getApplicationContext(), ProfileActivity.class));
}
});

AppCompatTextView navUserName = headerView.findViewById(R.id.atv_name_header);
navUserName.setText("Budi");

TextView navEmail = headerView.findViewById(R.id.tv_email_header);
navEmail.setText("budi@gmail.com");
}

/**
* Fragment
**/
private boolean loadFragment(Fragment fragment) {
//switching fragment
if (fragment != null) {
getSupportFragmentManager()
.beginTransaction()
.replace(R.id.content_frame, fragment)
.commit();
return true;
}
return false;
}

/**
* Menu Bottom Navigation Drawer
* */
@Override
public boolean onNavigationItemSelected(MenuItem item) {

Fragment fragment = null;

// Handle navigation view item clicks here, you can custom the fragment as you want.
switch (item.getItemId()) {
case R.id.menu_home:
fragment = new HomeFragment();
break;
case R.id.menu_pengurus:
fragment = new PengurusFragment();
break;
case R.id.menu_saran_dan_kritikan:
fragment = new SaranDanKritikanFragment();
break;
case R.id.menu_about:
fragment = new AboutFragment();
break;
case R.id.menu_logout:
dialogExit();
break;
}

DrawerLayout drawer = findViewById(R.id.drawer_layout);
drawer.closeDrawer(GravityCompat.START);
return loadFragment(fragment);
}

@Override
public boolean onPrepareOptionsMenu(Menu menu) {

//Hidden Menu Bard For All Fragments
menuHome = menu.findItem(R.id.menu_home);
menuPengurus = menu.findItem(R.id.menu_pengurus);
menuSaranDanKritikan = menu.findItem(R.id.menu_saran_dan_kritikan);
menuAbout = menu.findItem(R.id.menu_about);
menuLogout = menu.findItem(R.id.menu_logout);

if(menuHome != null && menuPengurus != null && menuSaranDanKritikan != null &&
menuAbout != null && menuLogout != null)

menuHome.setVisible(false);
menuPengurus.setVisible(false);
menuSaranDanKritikan.setVisible(false);
menuAbout.setVisible(false);
menuLogout.setVisible(false);

return super.onPrepareOptionsMenu(menu);
}

private void dialogExit() {
AlertDialog.Builder dialog = new AlertDialog.Builder(this);
dialog.setMessage("Apakah anda yakin ingin keluar?");
dialog.setPositiveButton("Ya", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialogInterface, int i) {
finish();
}
});
dialog.setNegativeButton("Tidak", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialogInterface, int i) {
dialogInterface.dismiss();
}
});
dialog.show();
}

@Override
public void onBackPressed() {
DrawerLayout drawer = findViewById(R.id.drawer_layout);
if (drawer.isDrawerOpen(GravityCompat.START)) {
drawer.closeDrawer(GravityCompat.START);
} else {

// klik double tap to exit
if (doubleBackToExitPressedOnce) {
finishAffinity();
return;
}

this.doubleBackToExitPressedOnce = true;
Toast.makeText(this, "Tap again to exit", Toast.LENGTH_SHORT).show();

new Handler().postDelayed(new Runnable() {

@Override
public void run() {
doubleBackToExitPressedOnce=false;
}
}, 2000);
}
}

@Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.menu_nav_drawer, menu);
return true;
}
}

That’s it. Now you have learn the implementation of the navigation drawer (modal drawer). Find full source code in below :

Questions? Comments? Contact us at yourfriends.medium.com

Sign up to discover human stories that deepen your understanding of the world.

Achmad Qomarudin
Achmad Qomarudin

Written by Achmad Qomarudin

Android Developer • UI/UX Enthusiast • Love to create apps exploration on github.com/achmadqomarudin • Have a question? find me on instagram.com/achmad_dev

No responses yet

Write a response