Android Navigation Drawer with Navigation Component in Android-Java

thumbnail

In this, tutorial, we will learn about navigation drawer with navigation component in Android-Java. Previously, we learn about navigation drawer in Android-Java using Androidx where we just change the text after navigation item is clicked. But, now we are adding fragment to each navigation item.

Start from adding dependency in build.gradle as below:

dependencies {
    implementation "androidx.core:core-ktx:1.1.0"
    implementation "com.android.support.constraint:constraint-layout:1.1.3"
    implementation "androidx.coordinatorlayout:coordinatorlayout:1.0.0"
    implementation 'com.google.android.material:material:1.0.0'// Drawer Layout
    implementation "androidx.drawerlayout:drawerlayout:1.0.0"

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

Next, open strings.xml, dimen.xml, colors.xml, and styles.xml located under res->values and add the below values.

strings.xml

<resources>
    <string name="app_name">Creative Android - Java</string>
    <string name="dashboard">Dashboard</string>
    <string name="favourite">Favourite</string>
    <string name="login">Login</string>
    <string name="profile">Profile</string>
    <string name="explore">Explore</string>
    <string name="trending">Trending</string>
    <string name="news">News</string>
    <string name="hello_world">Hello world!</string>
    <string name="action_settings">Settings</string>

    <string name="screen_dashboard">Dashboard Screen</string>
    <string name="screen_login">Login Screen</string>
    <string name="screen_explore">Explore Screen</string>
    <string name="screen_trending">Trending Screen</string>
    <string name="screen_profile">Profile Screen</string>
</resources>

dimen.xml

<?xml version="1.0" encoding="utf-8"?>
<resources xmlns:tools="http://schemas.android.com/tools">
    <dimen name="toolbar_elevation_size" tools:override="true">4dp</dimen>
    <dimen name="event_title_text_size" tools:override="true">20sp</dimen>
</resources>

colors.xml

<?xml version="1.0" encoding="utf-8"?>
<resources>
    <color name="colorPrimary">#008577</color>
    <color name="colorPrimaryDark">#00574B</color>
    <color name="colorAccent">#D81B60</color>
</resources>

styles.xml

<resources>

    <!-- Base application theme. -->
    <style name="AppTheme" parent="Theme.AppCompat.Light.DarkActionBar">
        <!-- Customize your theme here. -->
        <item name="colorPrimary">@color/colorPrimary</item>
        <item name="colorPrimaryDark">@color/colorPrimaryDark</item>
        <item name="colorAccent">@color/colorAccent</item>
        <item name="windowActionBar">false</item>
        <item name="windowNoTitle">true</item>
    </style>

    <!-- Disable windowActionBar. -->
    <style name="AppTheme.WithoutActionBar">
        <item name="windowActionBar">false</item>
        <item name="windowNoTitle">true</item>
    </style>

    <style name="ToolBarStyle" parent="ToolBarStyle.Base"/>

    <style name="ToolBarStyle.Base" parent="">
        <item name="popupTheme">@style/ThemeOverlay.AppCompat.Light</item>
        <item name="theme">@style/ThemeOverlay.AppCompat.Dark.ActionBar</item>
    </style>

    <style name="ToolBarStyle.Event" parent="ToolBarStyle">
        <item name="titleTextAppearance">@style/TextAppearance.Widget.Event.Toolbar.Title</item>
    </style>

    <style name="TextAppearance.Widget.Event.Toolbar.Title" parent="TextAppearance.Widget.AppCompat.Toolbar.Title">
        <!--Any text styling can be done here-->
        <item name="android:textStyle">normal</item>
        <item name="android:textSize">@dimen/event_title_text_size</item>
        <item name="android:textAlignment">center</item>
        <item name="android:textAllCaps">false</item>
        <item name="android:layout_gravity">center</item>
        <item name="android:gravity">center</item>
        <item name="android:ellipsize">end</item>
        <item name="android:maxLines">2</item>
    </style>

</resources>

Add several icons you need to add to the drawable folder, such as: exit to app, account box, apps, explore, and grade icon. Then under the res->menu, create file navigation_view_items.xml. The file is used to render navigation item we used in the navigation drawer.

navigation_view_items.xml

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

    <item
        android:id="@+id/navigation_dashboard"
        android:icon="@drawable/ic_apps_black_24dp"
        android:title="@string/dashboard" />
    <item
        android:id="@+id/navigation_login"
        android:icon="@drawable/ic_exit_to_app_black_24dp"
        android:title="@string/login" />

    <item
        android:id="@+id/navigation_explore"
        android:icon="@drawable/ic_explore_black_24dp"
        android:title="@string/explore" />
    <item
        android:id="@+id/navigation_trending"
        android:icon="@drawable/ic_grade_black_24dp"
        android:title="@string/trending" />

    <item
        android:id="@+id/navigation_profile"
        android:icon="@drawable/ic_account_box_black_24dp"
        android:title="@string/profile" />
</menu>

Under the res->layout, create file named with activity_dashboard.xml, navigation_header.xml, fragment_dashboard.xml, fragment_explorer.xml, fragment_login.xml, fragment_profile.xml, and fragment_trending.xml.

navigation_header.xml

<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="192dp"
    android:theme="@style/ThemeOverlay.AppCompat.Dark">

    <ImageView
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:scaleType="centerCrop"
        android:src="@color/colorPrimaryDark" />

    <ImageView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_gravity="bottom"
        android:layout_marginLeft="100dp"
        android:padding="30dp"
        android:src="@drawable/ic_launcher_background" />

    <LinearLayout
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_gravity="bottom"
        android:orientation="vertical">

        <TextView
            android:id="@+id/name"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_marginBottom="5dp"
            android:layout_marginLeft="16dp"
            android:text="USERNAME"
            android:textAppearance="@style/TextAppearance.AppCompat.Body1"
            android:textStyle="bold" />

        <TextView
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_marginBottom="16dp"
            android:layout_marginLeft="16dp"
            android:text="EMAIL"
            android:textColor="#fff" />
    </LinearLayout>
</FrameLayout>

fragment_dashboard.xml

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

    <androidx.appcompat.widget.AppCompatImageView
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:src="@drawable/ic_apps_black_24dp"
        android:layout_gravity="center" />

    <androidx.appcompat.widget.AppCompatTextView
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="@string/screen_dashboard"
        android:layout_gravity="center"
        android:gravity="center" />

</LinearLayout>

fragment_explorer.xml

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

    <androidx.appcompat.widget.AppCompatImageView
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:src="@drawable/ic_explore_black_24dp"
        android:layout_gravity="center" />

    <androidx.appcompat.widget.AppCompatTextView
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="@string/screen_explore"
        android:layout_gravity="center"
        android:gravity="center" />

</LinearLayout>

fragment_login.xml

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

    <androidx.appcompat.widget.AppCompatImageView
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:src="@drawable/ic_exit_to_app_black_24dp"
        android:layout_gravity="center" />

    <androidx.appcompat.widget.AppCompatTextView
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="@string/screen_login"
        android:layout_gravity="center"
        android:gravity="center" />

</LinearLayout>

fragment_profile.xml

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

    <androidx.appcompat.widget.AppCompatImageView
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:src="@drawable/ic_account_box_black_24dp"
        android:layout_gravity="center" />

    <androidx.appcompat.widget.AppCompatTextView
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="@string/screen_profile"
        android:layout_gravity="center"
        android:gravity="center" />

</LinearLayout>

fragment_trending.xml

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

    <androidx.appcompat.widget.AppCompatImageView
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:src="@drawable/ic_grade_black_24dp"
        android:layout_gravity="center" />

    <androidx.appcompat.widget.AppCompatTextView
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="@string/screen_trending"
        android:layout_gravity="center"
        android:gravity="center" />

</LinearLayout>

activity_dashboard.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/drawerLayout"
    android:layout_width="match_parent"
    android:layout_height="match_parent">
    <androidx.constraintlayout.widget.ConstraintLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        tools:context=".DashboardActivity">

        <com.google.android.material.appbar.AppBarLayout
            android:id="@+id/mainAppBar"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            app:layout_constraintTop_toTopOf="parent"
            app:layout_constraintStart_toStartOf="parent"
            app:layout_constraintEnd_toEndOf="parent"
            >
            <androidx.appcompat.widget.Toolbar
                style="@style/ToolBarStyle.Event"
                android:id="@+id/mainToolbar"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:minHeight="?attr/actionBarSize"
                android:background="?attr/colorPrimary"
                android:elevation="@dimen/toolbar_elevation_size">

            </androidx.appcompat.widget.Toolbar>
        </com.google.android.material.appbar.AppBarLayout>

        <fragment
            android:id="@+id/nav_host_fragment"
            android:name="androidx.navigation.fragment.NavHostFragment"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            app:defaultNavHost="true"
            app:navGraph="@navigation/nav_graph"
            app:layout_constraintTop_toBottomOf="@id/mainAppBar"
            app:layout_constraintStart_toStartOf="parent"
            app:layout_constraintEnd_toEndOf="parent"
            app:layout_constraintBottom_toBottomOf="parent" />

    </androidx.constraintlayout.widget.ConstraintLayout>

    <com.google.android.material.navigation.NavigationView
        android:id="@+id/navigation_view"
        android:layout_width="wrap_content"
        android:layout_height="match_parent"
        android:layout_gravity="start"
        android:fitsSystemWindows="true"
        app:headerLayout="@layout/navigation_header"
        app:itemIconTint="#ff1b6bae"
        app:itemTextColor="#333"
        app:menu="@menu/navigation_view_items" />
</androidx.drawerlayout.widget.DrawerLayout>

Create package named fragments and under this package will be created five fragment files.

DashboardFragment.java

package com.inpows.creativejava.fragments;

import android.content.Context;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;

import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.fragment.app.Fragment;

import com.inpows.creativejava.R;

public class DashboardFragment extends Fragment {

    @Override
    public void onAttach(@NonNull Context context) {
        super.onAttach(context);
    }

    @Nullable
    @Override
    public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
        return inflater.inflate(R.layout.fragment_dashboard, container, false);
    }
}

ExplorerFragment.java

package com.inpows.creativejava.fragments;

import android.content.Context;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;

import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.fragment.app.Fragment;

import com.inpows.creativejava.R;

public class ExplorerFragment extends Fragment {
    @Override
    public void onAttach(@NonNull Context context) {
        super.onAttach(context);
    }

    @Nullable
    @Override
    public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
        return inflater.inflate(R.layout.fragment_explorer, container, false);
    }

    @Override
    public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
        super.onViewCreated(view, savedInstanceState);
    }
}

LoginFragment.java

package com.inpows.creativejava.fragments;

import android.content.Context;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;

import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.fragment.app.Fragment;

import com.inpows.creativejava.R;

public class LoginFragment extends Fragment {
    @Override
    public void onAttach(@NonNull Context context) {
        super.onAttach(context);
    }

    @Nullable
    @Override
    public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
        return inflater.inflate(R.layout.fragment_login, container, false);
    }
}

ProfileFragment.java

package com.inpows.creativejava.fragments;

import android.content.Context;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;

import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.fragment.app.Fragment;

import com.inpows.creativejava.R;

public class ProfileFragment extends Fragment {
    @Override
    public void onAttach(@NonNull Context context) {
        super.onAttach(context);
    }

    @Nullable
    @Override
    public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
        return inflater.inflate(R.layout.fragment_profile, container, false);
    }
}

TrendingFragment.java

package com.inpows.creativejava.fragments;

import android.content.Context;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;

import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.fragment.app.Fragment;

import com.inpows.creativejava.R;

public class TrendingFragment extends Fragment {
    @Override
    public void onAttach(@NonNull Context context) {
        super.onAttach(context);
    }

    @Nullable
    @Override
    public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
        return inflater.inflate(R.layout.fragment_trending, container, false);
    }
}

Now we have all the required element in place. It’s time to open DashboardActivity.java and modify as below.

DashboardActivity.java

package com.inpows.creativejava;

import android.content.res.Configuration;
import android.os.Bundle;
import android.view.MenuItem;

import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.appcompat.app.ActionBarDrawerToggle;
import androidx.appcompat.app.AppCompatActivity;
import androidx.appcompat.widget.Toolbar;
import androidx.core.view.GravityCompat;
import androidx.drawerlayout.widget.DrawerLayout;
import androidx.navigation.NavController;
import androidx.navigation.Navigation;
import androidx.navigation.ui.NavigationUI;

import com.google.android.material.navigation.NavigationView;

import org.jetbrains.annotations.NotNull;

public class DashboardActivity extends AppCompatActivity implements
        NavigationView.OnNavigationItemSelectedListener{

    DrawerLayout drawerLayout;
    ActionBarDrawerToggle drawerToggle;
    NavigationView navigationView;
    Toolbar toolbar;
    NavController navController;

    // index to identify current nav menu item 
    public static int navItemIndex = 0;
    public List<Integer> navItemIndexList;

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

        toolbar = findViewById(R.id.mainToolbar);
        toolbar.setTitle(R.string.dashboard); 
        navItemIndexList = new ArrayList<Integer>();
        navItemIndexList.add(0);
        setSupportActionBar(toolbar);
        if (getSupportActionBar() != null){
            getSupportActionBar().setHomeButtonEnabled(false);
            getSupportActionBar().setDisplayHomeAsUpEnabled(true);
        }

        drawerLayout = findViewById(R.id.drawerLayout);
        drawerToggle = new ActionBarDrawerToggle(DashboardActivity.this, drawerLayout, R.string.hello_world, R.string.hello_world);
        drawerLayout.addDrawerListener(drawerToggle);
        drawerToggle.syncState();
        navigationView  = findViewById(R.id.navigation_view);
        navController = Navigation.findNavController(this, R.id.nav_host_fragment);
        NavigationUI.setupActionBarWithNavController(this, navController, drawerLayout);
        NavigationUI.setupWithNavController(navigationView, navController);
        navigationView.setNavigationItemSelectedListener(this);

    }

    @Override
    public boolean onSupportNavigateUp() {
        return NavigationUI.navigateUp(Navigation.findNavController(this, R.id.nav_host_fragment), drawerLayout);
    }

    @Override
    public void onPostCreate(Bundle savedInstanceState) {
        super.onPostCreate(savedInstanceState);
        drawerToggle.syncState();
    }

    @Override
    public void onBackPressed() {
        if (drawerLayout.isDrawerOpen(GravityCompat.START)) {
            drawerLayout.closeDrawer(GravityCompat.START);
            return;
        } 
        navItemIndexList.remove(navItemIndexList.size()-1);
        super.onBackPressed();
    }

    @Override
    public void onConfigurationChanged(@NotNull Configuration newConfig) {
        super.onConfigurationChanged(newConfig);
        drawerToggle.onConfigurationChanged(newConfig);
    }

    @Override
    public boolean onNavigationItemSelected(@NonNull MenuItem menuItem) {
        //Checking if the item is in checked state or not, if not make it in checked state
        if (menuItem.isChecked()) {
            menuItem.setChecked(false);
        } else {
            menuItem.setChecked(true);
        }
        menuItem.setChecked(true);
        drawerLayout.closeDrawer(GravityCompat.START);
        int id = menuItem.getItemId();
        if(id != navItemIndex){
            navItemIndex = id; 
            navItemIndexList.add(id);
            switch (id) {
                case R.id.navigation_dashboard:
                    //Do some thing here
                    // add navigation drawer item onclick method here
                    toolbar.setTitle(R.string.dashboard);
                    navController.navigate(R.id.dashboardFragment);
                    break;
                case R.id.navigation_explore:
                    //Do some thing here
                    // add navigation drawer item onclick method here
                    toolbar.setTitle(R.string.explore);
                    navController.navigate(R.id.explorerFragment);
                    break;
                case R.id.navigation_login:
                    //Do some thing here
                    // add navigation drawer item onclick method here
                    toolbar.setTitle(R.string.login);
                    navController.navigate(R.id.loginFragment);
                    break;
                case R.id.navigation_profile:
                    //Do some thing here
                    // add navigation drawer item onclick method here
                    toolbar.setTitle(R.string.profile);
                    navController.navigate(R.id.loginFragment);
                    break;
                case R.id.navigation_trending:
                    //Do some thing here
                    // add navigation drawer item onclick method here
                    toolbar.setTitle(R.string.profile);
                    navController.navigate(R.id.loginFragment);
                    break;
            }
        }
        return false;
    }

    @Override
    public boolean onOptionsItemSelected(@NonNull MenuItem item) {
        if (drawerToggle.onOptionsItemSelected(item)) {
            return true;
        }

        return super.onOptionsItemSelected(item);
    }
}

Run and test the app then you should be able to see the app as below.

Back To Top