post featured image

Bottom navigation bar setup tutorial – Android [XML]

Difficulty: Beginner

Implementing Bottom navigation on android can be a tricky task, since there isn’t clear instructions on how it can be implemented properly, in this article we are going to implement the material design ‘bottom navigation view’ with multiple back stacks that preserve their state when switching between different screens.

Setup

To use bottom navigation view we will need the material dependency get the latest version here.

//build.gradle (module)   
dependencies { 
implementation 'com.google.android.material:material:1.8.0'
}

In this example im going to use androidx navigation and safe args but feel free to skip them if you want.

plugins {
  id 'androidx.navigation.safeargs.kotlin'
}  
dependencies {
  def nav_version = "2.5.3"

  implementation "androidx.navigation:navigation-fragment-ktx:$nav_version"
  implementation "androidx.navigation:navigation-ui-ktx:$nav_version"
}
buildscript {
    repositories {
        google()
    }
    dependencies {
        classpath "androidx.navigation:navigation-safe-args-gradle-plugin:2.5.3"
    }
}

Adding our fragments

In our project we want to display a bottom navigation bar with three options Home, Profile and Favorites so lets create these fragments by right clicking our app package name and select new > Fragment > Blank

These fragments might have a lot redundant code that we won’t need so lets delete it and replace each fragment with this (don’t forget to change names for each fragment)

import android.os.Bundle
import android.view.View
import androidx.fragment.app.Fragment
import com.example.bottomnavsample.databinding.FragmentHomeBinding


class HomeFragment : Fragment(R.layout.fragment_home) {

    private var _binding: FragmentHomeBinding? = null
    private val binding get() = _binding!!


    override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
        super.onViewCreated(view, savedInstanceState)
        _binding = FragmentHomeBinding.bind(view)
    }

    override fun onDestroyView() {
        super.onDestroyView()
        _binding = null
    }
    
}

Creating a menu

To display our options in a bottom navigation view we will have to create a menu with the appropriate title, icon and id for each item. to create a menu right click on the res folder in android studio > New > Android Resource Directory, then from the resource type drop down choose menu and click OK.

Right click your newly created menu directory > New > Menu Resource File.

Add 3 items to your new menu with ids and icons, Notice the name of the ids for the menu items as they are important for navigation later.

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

    <item
        android:id="@+id/home_nav"
        android:icon="@drawable/ic_home_black_24dp"
        android:title="Home" />
    <item
        android:id="@+id/profile_nav"
        android:icon="@drawable/baseline_person_24"
        android:title="Profile" />
    <item
        android:id="@+id/favorite_nav"
        android:icon="@drawable/baseline_star_24"
        android:title="Favorite" />
</menu>

Creating the Navigation Graph

Right click the res folder > New > Android Resource Directory, from the window choose navigation as the resource type. Now create 4 new navigation graphs in this resource directory, the first one will be called main_graph the rest 3 will have the exact name as the ids from the menu items we just created (home_nav, profile_nav, favorite_nav)

Open up home_nav click the New Destination button and add your home fragment

Repeat the same for profile_nav and favorite_nav, and add the appropriate fragment for each one of them.

On main_graph click the New Destination button then add home_nav.xml, profile.xml and favorite.xml

Feel free to add more fragments and connect them with actions in each of your navigation graphs.

Connecting everything with bottom navigation view

In our activity_main.xml we want to add we will add a bottom navigation view and fragment container. Notice the attributes on fragment container name and navGraph.

navGraph points to the main graph that includes all of our other graph files, name value is set to NavHostFragment which is a class in androidx libraries that provides an area within your layout for self-contained navigation to occur. the NavHostFragment has a navController and a navigation state meaning the state of each of our options in the bottom navigation view will be saved and restored when switching items.

defaultNavHost gives us the expected behavior to navigate to the previous fragment when we press the back button.

<?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"
    xmlns:tools="http://schemas.android.com/tools"
    android:id="@+id/container"
    android:orientation="vertical"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <androidx.fragment.app.FragmentContainerView
        android:id="@+id/fragment_container"
        android:layout_width="match_parent"
        android:layout_height="0dp"
        android:layout_weight="1"
        android:name="androidx.navigation.fragment.NavHostFragment"
        app:navGraph="@navigation/main_graph"
        app:defaultNavHost="true"
        tools:layout="@layout/fragment_home" />

    <com.google.android.material.bottomnavigation.BottomNavigationView
        android:id="@+id/bottom_nav"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        app:menu="@menu/nav_menu"/>
    
</LinearLayout>

And last but not least we’ll have to attach the navController to our bottom navigation view in MainActivity


import android.os.Bundle
import androidx.appcompat.app.AppCompatActivity
import androidx.navigation.fragment.NavHostFragment
import androidx.navigation.fragment.findNavController
import androidx.navigation.ui.setupWithNavController
import com.example.bottomnavsample.databinding.ActivityMainBinding

class MainActivity : AppCompatActivity() {

    private lateinit var binding: ActivityMainBinding
    private lateinit var navController: NavController
    private lateinit var appBarConfiguration: AppBarConfiguration

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

        binding = ActivityMainBinding.inflate(layoutInflater)
        setContentView(binding.root)
        
        val navHostFragment = supportFragmentManager.findFragmentById(R.id.fragment_container) as NavHostFragment
        navController = navHostFragment.findNavController()
        
        //Give the action bar the correct title for the current screen (this uses the fragment label)
        appBarConfiguration = AppBarConfiguration(
            setOf(R.id.homeFragment, R.id.profileFragment,  R.id.favoriteFragment2)
        )
        //Connects the action bar with the nav controller
        setupActionBarWithNavController(navController, appBarConfiguration)

        binding.bottomNav.setupWithNavController(navController)
    }
    
    //gives functionality to the back button on the action bar
    override fun onSupportNavigateUp(): Boolean {
        return navController.navigateUp(appBarConfiguration)
    }
}
Demo

The sample project is available on Github.

0 0 votes
Article Rating
Subscribe
Notify of
guest

0 Comments
Inline Feedbacks
View all comments