Drawer Layout and Bottom Navigation with Navigation Components (Android — Kotlin) Example

Katwere Leo
4 min readMay 4, 2023

--

Navigation component is part of the Android Jetpack Libraries. It provides an easy and consistent way of implementing navigation within your Android App. Navigation component makes it extremely easy to implement the drawer layout and bottom navigation in an Android App.

Here is my implementation for both.

Prerequisites

  1. Android Studio
  2. Basic Knowledge of Kotlin Programming Language.
  3. Familiarity with Android Application Development.

Create New Project

To start, create a new Android Studio Project with an empty Activity template. In the project creation wizard, choose Kotlin as the language and select the minimum SDK version you want to support.

Add Dependencies

Add the following dependencies to your project’s build.gradle file.

 // Material Design Components
implementation 'com.google.android.material:material:1.8.0'

// Navigation component
implementation 'androidx.navigation:navigation-fragment-ktx:2.5.3'
implementation 'androidx.navigation:navigation-ui-ktx:2.5.3'

Fragments

Fragments serve as destinations in navigation. In this example, we will create four simple Fragments and add them to the navigation graph which we will create in the next step.

fragment_first.xml

<androidx.constraintlayout.widget.ConstraintLayout 
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"
xmlns:app="http://schemas.android.com/apk/res-auto"
tools:context=".fragments.FirstFragment">

<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="1"
android:textColor="@color/black"
android:textSize="100sp"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintBottom_toBottomOf="parent"/>

</androidx.constraintlayout.widget.ConstraintLayout>

Navigation Graph

Next, we create a navigation graph. A navigation graph is an xml file that defines the different screens in your app and the possible paths between them.

To create a new navigation graph, right click on your ‘res’ folder in your project and select ‘New > Android Resource File’. Set the filename to nav_graph and select “Navigation” as the resource type.

nav_graph.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/nav_graph"
app:startDestination="@+id/thirdFragment">

<fragment
android:id="@+id/firstFragment"
android:name="com.example.myapp.FirstFragment"
android:label="fragment_first"
tools:layout="@layout/fragment_first" />
<fragment
android:id="@+id/secondFragment"
android:name="com.example.myapp.SecondFragment"
android:label="fragment_second"
tools:layout="@layout/fragment_second" />
<fragment
android:id="@+id/thirdFragment"
android:name="com.example.myapp.ThirdFragment"
android:label="fragment_third"
tools:layout="@layout/fragment_third" />
<fragment
android:id="@+id/fourthFragment"
android:name="com.example.myapp.FourthFragment"
android:label="fragment_fourth"
tools:layout="@layout/fragment_fourth" />
</navigation>

In this example, we have added the four fragments to our navigation graph. The ‘startDestination’ attribute specifies the initial screen of the app, which is ‘thirdFragment’ in this case.

Drawer Layout

Next, we are going to set up a drawer layout with navigation. First, create a menu resource file in the ‘res/menu’ folder of our project.

main_menu.xml

<menu xmlns:android="http://schemas.android.com/apk/res/android">
<item
android:id="@+id/firstFragment"
android:title="First Screen" />
<item
android:id="@+id/secondFragment"
android:title="Second Screen" />
</menu>

Note: The id of items in the menu should match the id of the Fragments in the nav_graph.xml file.

Secondly, add the drawer layout in your activity_main.xml file.

activity_main.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"
android:id="@+id/drawer_layout"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fitsSystemWindows="true">

<!--Main Content Section-->

<androidx.constraintlayout.widget.ConstraintLayout
android:id="@+id/main_container"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">

<!-- Navhost Fragment-->

<fragment
android:id="@+id/nav_host_fragment"
android:name="androidx.navigation.fragment.NavHostFragment"
android:layout_width="0dp"
android:layout_height="0dp"
app:defaultNavHost="true"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:navGraph="@navigation/nav_graph" />

</androidx.constraintlayout.widget.ConstraintLayout>

<!--side navigation view -->
<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:menu="@menu/main_menu" />
</androidx.drawerlayout.widget.DrawerLayout>

When adding the drawer layout, here are a few things you should note.

  1. Drawer layout should be the parent layout.
  2. Drawer layout should have 2 children i.e the side navigation view and the layout containing the nav_host fragment.

Next, we will configure the appbar in the `MainActivity.kt` file using the `AppBarConfiguration` object. This will allow us to manage the behavior of the top-left navigation button. The button will toggle between a drawer icon and a back icon depending on the current navigation destination.

appBarConfiguration = AppBarConfiguration(navController.graph, 
binding.drawerLayout)

setupActionBarWithNavController(navController, appBarConfiguration)

‘NavigationUI.setupActionBarWithNavController’ performs following tasks:

  • Displays hamburger icon(drawer icon) when in top-level destination
  • Display up icon when not in top-level destination
  • Update title text based on the destination’s label

Next, we are going to set up a click listener for the navigation menu items.

binding.navView.setNavigationItemSelectedListener { menuItem ->
menuItem.isChecked = true
binding.drawerLayout.closeDrawers()

when (menuItem.itemId) {
R.id.firstFragment -> {
navController.navigate(R.id.firstFragment)
true
}
R.id.secondFragment -> {
navController.navigate(R.id.secondFragment)
true
}
else -> false
}
}

Now, in order to handle drawer icon click, we need to override onSupportNavigateUp’ method.

override fun onSupportNavigateUp(): Boolean {
return navController.navigateUp(appBarConfiguration) || super.onSupportNavigateUp()
}

This will handle opening of the drawer and back button clicks when a user is not in a top level destination.

And, that is it!!!. We have successfully added a the drawer layout.

Now, its time to add the bottom navigation.

Bottom Navigation

  1. Create menu for bottom navigation.
<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android">
<item android:id="@+id/thirdFragment"
android:title="Home"
android:icon="@drawable/ic_baseline_home_24"/>

<item android:id="@+id/fourthFragment"
android:title="Settings"
android:icon="@drawable/ic_baseline_settings_24"/>


</menu>

Note: The id of items in the menu should match the id of the Fragments in the nav_graph.xml file.

2. Add Bottom Navigation to the main_container in ‘activity_main.xml’

 <com.google.android.material.bottomnavigation.BottomNavigationView
android:id="@+id/bottom_nav_view"
style="@style/Widget.MaterialComponents.BottomNavigationView.Colored"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:layout_constraintBottom_toBottomOf="parent"
app:menu="@menu/bottom_nav"
/>

Finally, add the bottom navigation view to your `NavController` in the `MainActivity`.

// Find reference to bottom navigation view
val navView: BottomNavigationView = binding.bottomNavView

// Hook your navigation controller to bottom navigation view
navView.setupWithNavController(navController)

And that’s it. Run the app and you will be able to navigate between the different fragments.

Main Activity Code

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.nav_host_fragment) as NavHostFragment
navController = navHostFragment.navController

// App Bar Configuration
appBarConfiguration = AppBarConfiguration(navController.graph, binding.drawerLayout)
setupActionBarWithNavController(navController, appBarConfiguration)

// On Click listener for drawer layout menu items
binding.navView.setNavigationItemSelectedListener { menuItem ->
menuItem.isChecked = true
binding.drawerLayout.closeDrawers()

when (menuItem.itemId) {
R.id.firstFragment -> {
navController.navigate(R.id.firstFragment)
true
}
R.id.secondFragment -> {
navController.navigate(R.id.secondFragment)
true
}
else -> false
}
}

// Find reference to bottom navigation view
val navView: BottomNavigationView = binding.bottomNavView
// Hook your navigation controller to bottom navigation view
navView.setupWithNavController(navController)

}

override fun onSupportNavigateUp(): Boolean {
return navController.navigateUp(appBarConfiguration) || super.onSupportNavigateUp()
}


}

Main Activity 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"
android:id="@+id/drawer_layout"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fitsSystemWindows="true">

<!--Main Content Section-->

<androidx.constraintlayout.widget.ConstraintLayout
android:id="@+id/main_container"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">

<fragment
android:id="@+id/nav_host_fragment"
android:name="androidx.navigation.fragment.NavHostFragment"
android:layout_width="0dp"
android:layout_height="0dp"
app:defaultNavHost="true"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:navGraph="@navigation/nav_graph" />

<com.google.android.material.bottomnavigation.BottomNavigationView
android:id="@+id/bottom_nav_view"
style="@style/Widget.MaterialComponents.BottomNavigationView.Colored"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:layout_constraintBottom_toBottomOf="parent"
app:menu="@menu/bottom_nav" />

</androidx.constraintlayout.widget.ConstraintLayout>

<!--navigation View with drawer menu-->
<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:menu="@menu/main_menu" />
</androidx.drawerlayout.widget.DrawerLayout>

You can find the code on Github

Nice Coding !!

--

--