Based on Material Design Material.io official website Bottom Navigation component is definied as:

“Bottom navigation bars allow movement between primary destinations in an app.”

It is recommened to be used in these scenarios based on the offcial documentation of the Bottom Navigaiton API:

  • Top-level destinations that need to be accessible from anywhere in the app
  • Three to five destinations
  • Mobile or tablet only

And it is recommened not to be used in these scenarios:

  • Single tasks, such as viewing a single email
  • User preferences or settings

You can check andorid developer documentation page for BottomNavigationView API for full class details.

As you might have seen it most applications nowadays use Bottom Navigation View widget in thier apps.

In this tutorial we will build a sample Android app with four bars. Each bar opening a different fragment. We will use Java as programming language for this tutorial. You can use Kotlin it is the same procedure except different syntax.

Prerequisite

  • Android Studio 3.5
  • Java programming language

Create a new Empty Activity poject in Andorid Studio.

project-creation.png

The project will create a blank activity. You will have MainActivity.java file and the activity_main.xml file.

Adding BottomNavigationView API to the project

Since the component is part of Design Support library we have to impelement design library in dependecies section of build.gradle file.

1
2
3
dependencies {
implementation 'com.google.android.material:material:1.0.0' 
}

Later, add a FrameLayout and BottomNavigationView in res/layout/activity_main.xml. The Framelayout will act like a container that you can display the fragments that we will talk about later.

In this porject I set RelativeLayout as the main layout for my main activity. Further, I have added a custom toolbar as I always prefer to have my custom toolbar instead of the built on. It gives me more control over the toolbar. You can also ignore this if you want and follow the tutorial it will not affect the application.

You can use include tag to include the custom toolbar layout that we will create in res/layout/custom_toolbar. This way you can customize the toolbar independently. Here is the activity_main.xml file.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
    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">
    <include
        android:id="@+id/custom_toolbar"
        layout="@layout/custom_toolbar"/>
    <FrameLayout
        android:id="@+id/main_frame"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:layout_above="@id/bottomNavBar"
        android:layout_below="@id/custom_toolbar"/>   <com.google.android.material.bottomnavigation.BottomNavigationView
        android:id="@+id/bottomNavBar"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_alignParentBottom="true"
        app:labelVisibilityMode="labeled"
        app:menu="@menu/bottomnavmenu" />
</RelativeLayout>

Here is the custom_toolbar file in res/layout/custom_toolbar folder.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
<?xml version="1.0" encoding="utf-8"?>
<androidx.appcompat.widget.Toolbar
    android:id="@+id/custom_toolbar"
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:background="@color/sunsetOrange">

    <TextView
        android:text="@string/bottomnavbartitle"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:gravity="center"/>
</androidx.appcompat.widget.Toolbar>

There are two important xml attributes in the BottomNavigationView widget to consider:

  1. app: labelVisibilityMode: Used to have control over the icon and text. You can change per your preference.
  2. app: menu: Used to assing the navigation menu to be displayed .
1
2
3
4
5
6
7
<com.google.android.material.bottomnavigation.BottomNavigationView
        android:id="@+id/bottomNavBar"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_alignParentBottom="true"
        app:labelVisibilityMode="labeled"
        app:menu="@menu/bottomnavmenu" />

We will create the corresponding menu file in res/menu/bottomnavmenu. Below you can see the menu. We will add four items. Each item has and id, icon and a title attribute.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android">

    <item
        android:id="@+id/nav_home"
        android:icon="@drawable/ic_home_black_24dp"
        android:title="@string/nav_home" />
    <item
        android:id="@+id/nav_media"
        android:icon="@drawable/ic_perm_media_black_24dp"
        android:title="@string/nav_media" />
    <item
        android:id="@+id/nav_search"
        android:icon="@drawable/ic_search_black_24dp"
        android:title="@string/nav_search" />
    <item
        android:id="@+id/nav_setting"
        android:icon="@drawable/ic_settings_black_24dp"
        android:title="@string/nav_settings" />

</menu>

In the MainActivity.java file we will declare and initialize our instances:

1
2
3
4
// Declare and initialize Toolbar
        Toolbar toolbar = findViewById(R.id.custom_toolbar);
        setSupportActionBar(toolbar);
BottomNavigationView mainNav = findViewById(R.id.bottomNavBar); 

Adding Fragments

We will add four fragments to our project with their XML files. We will call them home, media, search, and setting.

The fragment’s xml file will have only one TextView showing the title of the fragment. All of them have similar attributes.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".fragments.HomeFragment">
    <TextView
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:gravity="center"
        android:textSize="30sp"
        android:text="@string/hello_home_fragment" />

</FrameLayout>

Later we have to declare and initialize the four fragments inside MainActivity.java file inside onCreate method to be used for item selection. Note: For this project we will do it inside onCreate but in your applicaiton if you use this instances for other operation then declare them globally in the class.

1
2
3
4
5
// Fragment declaration and initialization. 
        final HomeFragment mHomeFragment = new HomeFragment();
        final MediaFragment mMediaFragment = new MediaFragment();
        final SearchFragment mSearchFragment = new SearchFragment();
        final SettingFragment mSettingFragment = new SettingFragment();

Item Selection

Now if you run the app and click on the items nothign will happen. It is because BottomNavigationView item selection method is implemented.

First we will create a method that sets the fragment to be opened when the method is called.

1
2
3
4
5
6
// set fragments to the Bottom Nav items
    private void setFragment(Fragment fragment) {
        FragmentTransaction fragmentTransaction = getSupportFragmentManager().beginTransaction();
        fragmentTransaction.replace(R.id.main_frame, fragment);
        fragmentTransaction.commit();
    }

This method is replacing the container which is the FrameLayout with the id R.id.main_frame that we declared in res/layout/activity_main.xmlfile.

We will implement a void method called setOnNavigationItemSelectedListener based on android developer doc:

Set a listener that will be notified when a bottom navigation item is selected

At the same time beware of setOnNavigationItemReselectListener which is Set a listener that will be notified when the currently selected bottom navigation item is reselected.

This is the implementation of the item selection listner inside onCreate method.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
// Change the FrameLayout based on each item selection
        mainNav.setOnNavigationItemSelectedListener(new BottomNavigationView.OnNavigationItemSelectedListener() {
            @Override
            public boolean onNavigationItemSelected(@NonNull MenuItem menuItem) {
                switch (menuItem.getItemId()) {
                    case R.id.nav_home:
                        setFragment(mHomeFragment);
                        return true;
                    case R.id.nav_media:
                        setFragment(mMediaFragment);
                        return true;
                    case R.id.nav_search:
                        setFragment(mSearchFragment);
                        return true;
                    case R.id.nav_setting:
                        setFragment(mSettingFragment);
                        return true;
                    default:
                        return false;
                }
            }
        });
		// set default fragment
       setFragment(mHomeFragment);

To make the first item the selected item we set the fragmnet to the first one with is the instance of HomeFragment.

Now the last step is to change the theme of the app to be NoActionBar for our custom toolbar to work in res/values/styles.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
resources>

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

</resources>

BottomNavigationView is one of the essential components of Andorid Applicaiton Developement that most apps use it nowadays. For sure it is an easy widget to use.

app-runnig.png

You can find the source code in this Github repo.