Navigation drawer is a popular design pattern used in modern Android apps to provide easy access to app navigation. With the Navigation Component in Android Studio, building navigation drawers has become even easier for developers using Kotlin. In this blog post, we'll explore how to implement a navigation drawer using Navigation Component in Android Studio with Kotlin.
Step 1: Add the Navigation Component to Your Project
To use the Navigation Component, you need to add the following dependencies to your app-level build.gradle file:
build.gradle
dependencies {
implementation 'androidx.core:core-ktx:1.8.0'
implementation 'androidx.appcompat:appcompat:1.6.1'
implementation 'com.google.android.material:material:1.5.0'
implementation 'androidx.constraintlayout:constraintlayout:2.1.4'
testImplementation 'junit:junit:4.13.2'
androidTestImplementation 'androidx.test.ext:junit:1.1.5'
androidTestImplementation 'androidx.test.espresso:espresso-core:3.5.1'
implementation 'de.hdodenhof:circleimageview:3.1.0'
// Kotlin
def nav_version = "2.5.3"
implementation "androidx.navigation:navigation-fragment-ktx:$nav_version"
implementation "androidx.navigation:navigation-ui-ktx:$nav_version"
}
Step 2: Add theme attributes for better design
themes.xml
<resources xmlns:tools="http://schemas.android.com/tools">
<!-- Base application theme. -->
<style name="Base.Theme.MyApplication" parent="Theme.Material3.Dark.NoActionBar">
<!-- Customize your light theme here. -->
<!-- <item name="colorPrimary">@color/my_light_primary</item> -->
<item name="android:windowTranslucentStatus">true</item>
<item name="android:windowLightStatusBar">true</item>
<item name="android:windowDrawsSystemBarBackgrounds">false</item>
</style>
<style name="Theme.MyApplication" parent="Base.Theme.MyApplication" />
</resources>
Step 3: Add string attributes for drawer open and close
strings.xml
<resources>
<string name="app_name">My Application</string>
<string name="navigation_drawer_open">Open navigation drawer</string>
<string name="navigation_drawer_close">Close navigation drawer</string>
<!-- TODO: Remove or change this placeholder text -->
<string name="hello_blank_fragment">Hello blank fragment</string>
</resources>
nav_graph.xml
<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/fragmentA"
>
<fragment
android:id="@+id/fragmentA"
android:name="com.example.myapplication.Fragment_A"
tools:layout="@layout/fragment__a">
<action
android:id="@+id/action_fragmentA_to_fragmentB"
app:destination="@id/fragmentB" />
</fragment>
<fragment
android:id="@+id/fragmentB"
android:name="com.example.myapplication.Fragment_B"
tools:layout="@layout/fragment__b">
<action
android:id="@+id/action_fragmentB_to_fragmentC"
app:destination="@id/fragmentC" />
</fragment>
<fragment
android:id="@+id/fragmentC"
android:name="com.example.myapplication.Fragment_C"
tools:layout="@layout/fragment__c" />
</navigation>
nav_menu.xml
<menu xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
tools:showIn="navigation_view">
<group android:checkableBehavior="single">
<item
android:id="@+id/fragment_a"
android:title="Fragment A" />
<item
android:id="@+id/fragment_b"
android:title="Fragment B" />
<item
android:id="@+id/fragment_c"
android:title="Fragment C" />
</group>
</menu>
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"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="@+id/drawer_layout"
android:fitsSystemWindows="false"
tools:context=".MainActivity">
<!-- android:fitsSystemWindows="false" -->
<androidx.coordinatorlayout.widget.CoordinatorLayout
android:layout_width="match_parent"
android:layout_height="match_parent">
<com.google.android.material.appbar.AppBarLayout
android:layout_width="match_parent"
android:gravity="bottom"
android:background="@color/white"
android:layout_height="85dp">
<androidx.appcompat.widget.Toolbar
android:id="@+id/toolbar"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
android:textStyle="bold"
app:titleTextColor="@color/black"
android:textColor="@color/black" />
</com.google.android.material.appbar.AppBarLayout>
<!-- Add your app's content here -->
<androidx.fragment.app.FragmentContainerView
android:id="@+id/nav_host_fragment"
android:name="androidx.navigation.fragment.NavHostFragment"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintBottom_toBottomOf="parent"
app:defaultNavHost="true"
app:layout_constraintTop_toBottomOf="@id/toolbar"
android:layout_marginTop="85dp"
app:navGraph="@navigation/nav_graph" />
</androidx.coordinatorlayout.widget.CoordinatorLayout>
<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"
android:background="@color/white"
app:itemTextColor="@color/black"
app:menu="@menu/nav_menu" />
</androidx.drawerlayout.widget.DrawerLayout>
fragment_A.xml
<?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"
android:background="@android:color/darker_gray"
tools:context=".Fragment_A">
<!-- TODO: Update blank fragment layout -->
<TextView
android:layout_marginTop="200dp"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:textSize="50dp"
android:textColor="@color/black"
android:textAlignment="center"
android:text="Fragment A" />
</FrameLayout>
fragment_B.xml
<?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"
android:background="@android:color/darker_gray"
tools:context=".Fragment_B">
<TextView
android:layout_marginTop="200dp"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:textSize="50dp"
android:textColor="@color/black"
android:textAlignment="center"
android:text="Fragment B" />
</FrameLayout>
fragment_C.xml
<?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"
android:background="@android:color/darker_gray"
tools:context=".Fragment_C">
<TextView
android:layout_marginTop="200dp"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:textSize="50dp"
android:textColor="@color/black"
android:textAlignment="center"
android:text="Fragment C" />
</FrameLayout>
MainActivity.kt
import android.content.res.Configuration
import android.os.Bundle
import android.view.MenuItem
import android.widget.Toast
import androidx.appcompat.app.ActionBarDrawerToggle
import androidx.appcompat.app.AppCompatActivity
import androidx.core.view.GravityCompat
import androidx.drawerlayout.widget.DrawerLayout
import androidx.navigation.NavController
import androidx.navigation.fragment.NavHostFragment
import androidx.navigation.ui.AppBarConfiguration
import androidx.navigation.ui.setupActionBarWithNavController
import androidx.navigation.ui.setupWithNavController
import com.google.android.material.navigation.NavigationView
class MainActivity : AppCompatActivity() {
private lateinit var drawerLayout: DrawerLayout
private lateinit var navigationView: NavigationView
private lateinit var toggle: ActionBarDrawerToggle
private lateinit var navController: NavController
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
val navHostFragment = supportFragmentManager.findFragmentById(R.id.nav_host_fragment) as NavHostFragment
navController = navHostFragment.navController
drawerLayout = findViewById(R.id.drawer_layout)
setSupportActionBar(findViewById(R.id.toolbar))
supportActionBar?.setDisplayHomeAsUpEnabled(true)
navigationView = findViewById(R.id.nav_view)
navigationView.setupWithNavController(navController)
val drawer_layout = findViewById<DrawerLayout>(R.id.drawer_layout)
val appBarConfiguration = AppBarConfiguration(navController.graph, drawer_layout)
setupActionBarWithNavController(navController, appBarConfiguration)
toggle = ActionBarDrawerToggle(
this,
drawerLayout,
findViewById(R.id.toolbar),
R.string.navigation_drawer_open,
R.string.navigation_drawer_close
)
drawerLayout.addDrawerListener(toggle)
navigationView.setNavigationItemSelectedListener { menuItem ->
when (menuItem.itemId) {
R.id.fragment_a -> {
supportFragmentManager.beginTransaction().replace(R.id.nav_host_fragment, Fragment_A()).commit()
drawerLayout.closeDrawer(GravityCompat.START)
true
}
R.id.fragment_b -> {
supportFragmentManager.beginTransaction().replace(R.id.nav_host_fragment, Fragment_B()).commit()
drawerLayout.closeDrawer(GravityCompat.START)
true
}
R.id.fragment_c -> {
supportFragmentManager.beginTransaction().replace(R.id.nav_host_fragment, Fragment_C()).commit()
drawerLayout.closeDrawer(GravityCompat.START)
true
}
else -> false
}
}
}
override fun onPostCreate(savedInstanceState: Bundle?) {
super.onPostCreate(savedInstanceState)
toggle.syncState()
}
override fun onConfigurationChanged(newConfig: Configuration) {
super.onConfigurationChanged(newConfig)
toggle.onConfigurationChanged(newConfig)
}
override
fun onOptionsItemSelected(item: MenuItem): Boolean {
return when (item.itemId) {
android.R.id.home -> {
drawerLayout.openDrawer(GravityCompat.START)
true
}
else -> super.onOptionsItemSelected(item)
}
}
override fun onSupportNavigateUp(): Boolean {
return navController.navigateUp() || super.onSupportNavigateUp()
}
}