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

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.

--

--

--

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

Love podcasts or audiobooks? Learn on the go with our new app.

Token-based authentication & REST API Implementation for Android|Kotlin apps

Flutter widget life-cycle debug

How to handle an app with both pre-AndroidX and AndroidX dependencies

Automating Beautiful Screenshots Using Jetpack Compose

Get Started Your First Mobile Top Down Shooting Game Development With Unity Visual Scripting Part 7

Android: Infinite Carousel with Coroutines and ViewPager1

Publish a multi-module Java/Android library to Maven Central + GitHub CI automation at 2021

Dagger and Multi-module Traveloka Android App

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store
Golap Gunjan Barman

Golap Gunjan Barman

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

More from Medium

Simple custom shadow on Android

Android Studio KeyBoard Shortcuts

Beginning Android Development Resources

Implementing Wallet Payments in Android Apps