Navigation Drawer with Fragments in Android using Kotlin | Navigation drawer with fragments

Golap Gunjan Barman
5 min readDec 18, 2021

Navigation Drawer with Fragments in Android using Kotlin | Navigation drawer with fragments

In this blog, we are going to see how to create a beautiful navigation drawer with fragments in android using kotlin.

- Here we are going to use a beautiful navigation drawer dependency ‘com.shreyaspatil:MaterialNavigationView:1.2’

- Using this dependency we can create a material navigation drawer view.

Implementation

main_menu

<?xml version=”1.0" encoding=”utf-8"?>
<menu xmlns:android=”http://schemas.android.com/apk/res/android"
xmlns:app=”http://schemas.android.com/apk/res-auto">
<item android:id=”@+id/action_default”
android:title=”Default”
app:showAsAction=”never”
android:orderInCategory=”100"/>
<item android:id=”@+id/action_round_rect”
android:title=”Rounded Rectangle”
app:showAsAction=”never”
android:orderInCategory=”100"/>
<item android:id=”@+id/action_round_right”
android:title=”Rounded Right Corner”
app:showAsAction=”never”
android:orderInCategory=”100"/>
</menu>

activity_main_drawer

<?xml version=”1.0" encoding=”utf-8"?>
<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/nav_home”
android:title=”@string/home”
android:icon=”@drawable/ic_baseline_home_24"/>
<item
android:id=”@+id/nav_gallery”
android:title=”@string/gallery”
android:icon=”@drawable/ic_baseline_image_24"/>
<item
android:id=”@+id/nav_slideshow”
android:title=”@string/slideshow”
android:icon=”@drawable/ic_baseline_slideshow”/>
<item
android:id=”@+id/nav_tools”
android:title=”@string/tools”
android:icon=”@drawable/ic_baseline_settings_24"/>
</group>
<item android:title=”@string/communication”>
<menu>
<group android:checkableBehavior=”single”>
<item android:id=”@+id/nav_share”
android:title=”@string/share”
android:icon=”@drawable/ic_baseline_share_24"/>
<item android:id=”@+id/nav_send”
android:title=”@string/send”
android:icon=”@drawable/ic_baseline_send_24"/>
</group>
</menu>
</item>
</menu>

Add fragments. Here I used 6 fragments. So according to that, I created the view models for 6 fragments.

HomeViewModel.java

package com.codewithgolap.materialnavdrawer.Home
import androidx.lifecycle.LiveData
import androidx.lifecycle.MutableLiveData
import androidx.lifecycle.ViewModel
class HomeViewModel : ViewModel() {
private val _text = MutableLiveData<String>().apply {
value = “This is Home Fragment”
}
val text : LiveData<String> = _text
}

GalleryViewModel.java

package com.codewithgolap.materialnavdrawer.Gallery
import androidx.lifecycle.LiveData
import androidx.lifecycle.MutableLiveData
import androidx.lifecycle.ViewModel
class GalleryViewModel :ViewModel() {
private val _text = MutableLiveData<String>().apply {
value = “This is Galley Fragment”
}
val text : LiveData<String> = _text
}

SlideShowViewModel.java

package com.codewithgolap.materialnavdrawer.Slideshow
import androidx.lifecycle.LiveData
import androidx.lifecycle.MutableLiveData
import androidx.lifecycle.ViewModel
class SlideshowViewModel : ViewModel() {
private val _text = MutableLiveData<String>().apply {
value = “This is Slideshow Fragment”
}
val text : LiveData<String> = _text
}

ShareViewModel.java

package com.codewithgolap.materialnavdrawer.Share
import androidx.lifecycle.LiveData
import androidx.lifecycle.MutableLiveData
import androidx.lifecycle.ViewModel
class ShareViewModel : ViewModel() {
private val _text = MutableLiveData<String>().apply {
value = “This is Share Fragment”
}
val text : LiveData<String> = _text
}

ToolsViewModel.java

package com.codewithgolap.materialnavdrawer.Tools
import androidx.lifecycle.LiveData
import androidx.lifecycle.MutableLiveData
import androidx.lifecycle.ViewModel
class ToolsViewModel : ViewModel() {
private val _text = MutableLiveData<String>().apply {
value = “This is Tools Fragment”
}
val text : LiveData<String> = _text
}

SendViewModel.java

package com.codewithgolap.materialnavdrawer.Send
import androidx.lifecycle.LiveData
import androidx.lifecycle.MutableLiveData
import androidx.lifecycle.ViewModel
class SendViewModel : ViewModel() {
private val _text = MutableLiveData<String>().apply {
value = “This is Send Fragment”
}
val text : LiveData<String> = _text
}

fragment_home.xml

<?xml version=”1.0" encoding=”utf-8"?>
<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=”.Home.HomeFragment”>
<! — TODO: Update blank fragment layout →
<TextView
android:id=”@+id/text_home”
android:layout_width=”match_parent”
android:layout_height=”wrap_content”
android:textAlignment=”center”
android:layout_marginEnd=”8dp”
android:layout_marginTop=”8dp”
android:layout_marginStart=”8dp”
app:layout_constraintEnd_toEndOf=”parent”
app:layout_constraintStart_toStartOf=”parent”
app:layout_constraintTop_toTopOf=”parent” />
</androidx.constraintlayout.widget.ConstraintLayout>

fragment_gallery.xml

<?xml version=”1.0" encoding=”utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout 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=”.Gallery.GalleryFragment”>
<! — TODO: Update blank fragment layout →
<TextView
android:id=”@+id/text_gallery”
android:layout_width=”match_parent”
android:layout_height=”wrap_content”
android:textAlignment=”center”
android:layout_marginEnd=”8dp”
android:layout_marginTop=”8dp”
android:layout_marginStart=”8dp”
app:layout_constraintEnd_toEndOf=”parent”
app:layout_constraintStart_toStartOf=”parent”
app:layout_constraintTop_toTopOf=”parent” />
</androidx.constraintlayout.widget.ConstraintLayout>

fragment_send.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”
xmlns:app=”http://schemas.android.com/apk/res-auto"
tools:context=”.Send.SendFragment”>
<! — TODO: Update blank fragment layout →
<TextView
android:id=”@+id/text_send”
android:layout_width=”match_parent”
android:layout_height=”wrap_content”
android:textAlignment=”center”
android:layout_marginEnd=”8dp”
android:layout_marginTop=”8dp”
android:layout_marginStart=”8dp”
app:layout_constraintEnd_toEndOf=”parent”
app:layout_constraintStart_toStartOf=”parent”
app:layout_constraintTop_toTopOf=”parent” />
</FrameLayout>

fragment_slideshow.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”
xmlns:app=”http://schemas.android.com/apk/res-auto"
tools:context=”.Slideshow.SlideshowFragment”>
<! — TODO: Update blank fragment layout →
<TextView
android:id=”@+id/text_slideshow”
android:layout_width=”match_parent”
android:layout_height=”wrap_content”
android:textAlignment=”center”
android:layout_marginEnd=”8dp”
android:layout_marginTop=”8dp”
android:layout_marginStart=”8dp”
app:layout_constraintEnd_toEndOf=”parent”
app:layout_constraintStart_toStartOf=”parent”
app:layout_constraintTop_toTopOf=”parent” />
</FrameLayout>

fragment_share.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”
xmlns:app=”http://schemas.android.com/apk/res-auto"
tools:context=”.Share.ShareFragment”>
<! — TODO: Update blank fragment layout →
<TextView
android:id=”@+id/text_share”
android:layout_width=”match_parent”
android:layout_height=”wrap_content”
android:textAlignment=”center”
android:layout_marginEnd=”8dp”
android:layout_marginTop=”8dp”
android:layout_marginStart=”8dp”
app:layout_constraintEnd_toEndOf=”parent”
app:layout_constraintStart_toStartOf=”parent”
app:layout_constraintTop_toTopOf=”parent” />
</FrameLayout>

fragment_tools.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”
xmlns:app=”http://schemas.android.com/apk/res-auto"
tools:context=”.Tools.ToolsFragment”>
<! — TODO: Update blank fragment layout →
<TextView
android:id=”@+id/text_tools”
android:layout_width=”match_parent”
android:layout_height=”wrap_content”
android:textAlignment=”center”
android:layout_marginEnd=”8dp”
android:layout_marginTop=”8dp”
android:layout_marginStart=”8dp”
app:layout_constraintEnd_toEndOf=”parent”
app:layout_constraintStart_toStartOf=”parent”
app:layout_constraintTop_toTopOf=”parent” />
</FrameLayout>

HomeFragment.java

package com.codewithgolap.materialnavdrawer.Home
import android.os.Bundle
import androidx.fragment.app.Fragment
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.TextView
import androidx.lifecycle.Observer
import androidx.lifecycle.ViewModelProviders
import com.codewithgolap.materialnavdrawer.Gallery.GalleryViewModel
import com.codewithgolap.materialnavdrawer.R
class HomeFragment : Fragment() {
private lateinit var homeViewModel: HomeViewModel
override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
homeViewModel = ViewModelProviders.of(this).get(HomeViewModel::class.java)
val root = inflater.inflate(R.layout.fragment_gallery, container, false)
val textView: TextView = root.findViewById(R.id.text_gallery)
homeViewModel.text.observe(viewLifecycleOwner, Observer {
textView.text = it
})
// Inflate the layout for this fragment
return root
}
}

GallaryFragment.java

package com.codewithgolap.materialnavdrawer.Gallery
import android.os.Bundle
import androidx.fragment.app.Fragment
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.TextView
import androidx.lifecycle.Observer
import androidx.lifecycle.ViewModelProvider
import androidx.lifecycle.ViewModelProviders
import com.codewithgolap.materialnavdrawer.R
class GalleryFragment : Fragment() {
private lateinit var galleryViewModel: GalleryViewModel
override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
galleryViewModel = ViewModelProviders.of(this).get(GalleryViewModel::class.java)
val root = inflater.inflate(R.layout.fragment_gallery, container, false)
val textView: TextView = root.findViewById(R.id.text_gallery)
galleryViewModel.text.observe(viewLifecycleOwner, Observer {
textView.text = it
})
// Inflate the layout for this fragment
return root
}

}

SlideShowFragment.java

package com.codewithgolap.materialnavdrawer.Slideshow
import android.os.Bundle
import androidx.fragment.app.Fragment
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.TextView
import androidx.lifecycle.Observer
import androidx.lifecycle.ViewModelProviders
import com.codewithgolap.materialnavdrawer.Gallery.GalleryViewModel
import com.codewithgolap.materialnavdrawer.R
class SlideshowFragment : Fragment() {
private lateinit var slideshowViewModel: SlideshowViewModel
override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
slideshowViewModel = ViewModelProviders.of(this).get(SlideshowViewModel::class.java)
val root = inflater.inflate(R.layout.fragment_gallery, container, false)
val textView: TextView = root.findViewById(R.id.text_gallery)
slideshowViewModel.text.observe(viewLifecycleOwner, Observer {
textView.text = it
})
// Inflate the layout for this fragment
return root
}

}

ShareFragment.java

package com.codewithgolap.materialnavdrawer.Share
import android.os.Bundle
import androidx.fragment.app.Fragment
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.TextView
import androidx.lifecycle.Observer
import androidx.lifecycle.ViewModelProviders
import com.codewithgolap.materialnavdrawer.Gallery.GalleryViewModel
import com.codewithgolap.materialnavdrawer.R
class ShareFragment : Fragment() {
private lateinit var shareViewModel: ShareViewModel
override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
shareViewModel = ViewModelProviders.of(this).get(ShareViewModel::class.java)
val root = inflater.inflate(R.layout.fragment_gallery, container, false)
val textView: TextView = root.findViewById(R.id.text_gallery)
shareViewModel.text.observe(viewLifecycleOwner, Observer {
textView.text = it
})
// Inflate the layout for this fragment
return root
}

}

SendFragment.java

package com.codewithgolap.materialnavdrawer.Send
import android.os.Bundle
import androidx.fragment.app.Fragment
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.TextView
import androidx.lifecycle.Observer
import androidx.lifecycle.ViewModelProviders
import com.codewithgolap.materialnavdrawer.Gallery.GalleryViewModel
import com.codewithgolap.materialnavdrawer.R
class SendFragment : Fragment() {
private lateinit var sendViewModel: SendViewModel
override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
sendViewModel = ViewModelProviders.of(this).get(SendViewModel::class.java)
val root = inflater.inflate(R.layout.fragment_gallery, container, false)
val textView: TextView = root.findViewById(R.id.text_gallery)
sendViewModel.text.observe(viewLifecycleOwner, Observer {
textView.text = it
})
// Inflate the layout for this fragment
return root
}

}

ToolsFragment.java

package com.codewithgolap.materialnavdrawer.Tools
import android.os.Bundle
import androidx.fragment.app.Fragment
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.TextView
import androidx.lifecycle.Observer
import androidx.lifecycle.ViewModelProviders
import com.codewithgolap.materialnavdrawer.Gallery.GalleryViewModel
import com.codewithgolap.materialnavdrawer.R
class ToolsFragment : Fragment() {
private lateinit var toolsViewModel: ToolsViewModel
override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
toolsViewModel = ViewModelProviders.of(this).get(ToolsViewModel::class.java)
val root = inflater.inflate(R.layout.fragment_gallery, container, false)
val textView: TextView = root.findViewById(R.id.text_gallery)
toolsViewModel.text.observe(viewLifecycleOwner, Observer {
textView.text = it
})
// Inflate the layout for this fragment
return root
}
}

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”
tools:context=”.MainActivity”
android:fitsSystemWindows=”true”
tools:openDrawer=”start”
android:id=”@+id/drawer_layout”>
<include layout=”@layout/app_bar_main”
android:layout_width=”match_parent”
android:layout_height=”match_parent”/>
<com.shreyaspatil.material.navigationview.MaterialNavigationView
android:layout_width=”wrap_content”
android:layout_height=”match_parent”
android:id=”@+id/nav_view”
android:layout_gravity=”start”
android:theme=”@style/Widget.NavigationView.RippleEffect”
app:headerLayout=”@layout/nav_header_main”
app:insetForeground=”@android:color/transparent”
app:itemIconTint=”@color/navigation_item_tint”
app:itemStyle=”default_style”
app:itemTextColor=”@color/navigation_item_tint”
app:menu=”@menu/activity_main_drawer”
android:background=”@color/colorPrimary”/>
</androidx.drawerlayout.widget.DrawerLayout>

MainActivtiy.java

package com.codewithgolap.materialnavdrawer
import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import android.view.Menu
import android.view.MenuItem
import androidx.appcompat.widget.Toolbar
import androidx.drawerlayout.widget.DrawerLayout
import androidx.navigation.findNavController
import androidx.navigation.ui.AppBarConfiguration
import androidx.navigation.ui.navigateUp
import androidx.navigation.ui.setupActionBarWithNavController
import androidx.navigation.ui.setupWithNavController
import com.shreyaspatil.material.navigationview.MaterialNavigationView
class MainActivity : AppCompatActivity() {
private lateinit var appBarConfiguration: AppBarConfiguration
private lateinit var navView : MaterialNavigationView
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
val toolbar: Toolbar = findViewById(R.id.toolbar)
setSupportActionBar(toolbar)
val drawerLayout : DrawerLayout = findViewById(R.id.drawer_layout)
navView = findViewById(R.id.nav_view)
val navController = findNavController(R.id.nav_host_fragemnt)
//passing each menu ID as a set of IDs bcz each menu should be considered as top level destinations
appBarConfiguration = AppBarConfiguration(
setOf(
R.id.nav_home, R.id.nav_gallery, R.id.nav_slideshow, R.id.nav_tools, R.id.nav_share, R.id.nav_send
), drawerLayout
)
setupActionBarWithNavController(navController, appBarConfiguration)
navView.setupWithNavController(navController)
//show itemstyle
println(“ItemStyle=${navView.getItemStyle()}”)
}
override fun onCreateOptionsMenu(menu: Menu?): Boolean {
menuInflater.inflate(R.menu.main_menu, menu)
return true
}
override fun onOptionsItemSelected(item: MenuItem): Boolean {
when (item.itemId){
R.id.default_style -> {
navView.setItemStyle(MaterialNavigationView.ITEM_STYLE_DEFAULT)
}
R.id.action_round_rect -> {
navView.setItemStyle(MaterialNavigationView.ITEM_STYLE_ROUND_RECTANGLE)
}
R.id.action_round_right -> {
navView.setItemStyle(MaterialNavigationView.ITEM_STYLE_ROUND_RIGHT)
}
}
return false
}
override fun onSupportNavigateUp(): Boolean {
val navController = findNavController(R.id.nav_host_fragemnt)
return navController.navigateUp(appBarConfiguration) || super.onSupportNavigateUp()
}
}

Watch the full video to understand it clearly.

Don’t forget to subscribe to the channel and hit the like button.

--

--

Golap Gunjan Barman

Hi everyone, myself Golap an Android app developer with UI/UX designer.