How To Set Up Navigation Component With Navigation Drawer In Android?
Solution 1:
How do I set up navigation component with navigation drawer?
How do I use it in my app?
The navigation drawer set up differs a little when it comes to Navigation component.
Note, if you create a new app with drawer navigation, the current tutorial is not needed. However I'm going to explain some things that might look strange around here and if you decide to add a drawer at a later stage of the app
First, you need to set up your activity_main.xml
and MainActivity
to be ready for the Navigation Architecture:
<?xml version="1.0" encoding="utf-8"?><androidx.drawerlayout.widget.DrawerLayoutxmlns: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/drawer_layout"android:layout_width="match_parent"android:layout_height="match_parent"android:fitsSystemWindows="true"tools:openDrawer="start"><includelayout="@layout/app_bar_main"android:layout_width="match_parent"android:layout_height="match_parent" /><com.google.android.material.navigation.NavigationViewandroid:id="@+id/nav_view"android:layout_width="wrap_content"android:layout_height="match_parent"android:layout_gravity="start"android:fitsSystemWindows="true"app:headerLayout="@layout/nav_header_main"app:menu="@menu/activity_main_drawer" /></androidx.drawerlayout.widget.DrawerLayout>
where app_bar_main
is just:
<?xml version="1.0" encoding="utf-8"?><androidx.coordinatorlayout.widget.CoordinatorLayoutxmlns: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"><com.google.android.material.appbar.AppBarLayoutandroid:layout_width="match_parent"android:layout_height="wrap_content"android:theme="@style/AppTheme.AppBarOverlay"><androidx.appcompat.widget.Toolbarandroid:id="@+id/toolbar"android:layout_width="match_parent"android:layout_height="?attr/actionBarSize"android:background="?attr/colorPrimary"app:popupTheme="@style/AppTheme.PopupOverlay" /></com.google.android.material.appbar.AppBarLayout><includelayout="@layout/content_main" /></androidx.coordinatorlayout.widget.CoordinatorLayout>
And the content_main
is where your fragments are going to be held:
<?xml version="1.0" encoding="utf-8"?><androidx.constraintlayout.widget.ConstraintLayoutxmlns: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"app:layout_behavior="@string/appbar_scrolling_view_behavior"tools:showIn="@layout/app_bar_main"><fragmentandroid:id="@+id/nav_host_fragment"android:name="androidx.navigation.fragment.NavHostFragment"android:layout_width="match_parent"android:layout_height="match_parent"app:defaultNavHost="true"app:layout_constraintLeft_toLeftOf="parent"app:layout_constraintRight_toRightOf="parent"app:layout_constraintTop_toTopOf="parent"app:navGraph="@navigation/mobile_navigation" /></androidx.constraintlayout.widget.ConstraintLayout>
Things you should know: The activity mustn't have a AppBar set on AndroidManifest.xml
:
android:theme="@style/AppTheme.NoActionBar"
If you notice app:menu="@menu/activity_main_drawer"
in the NavigationView
tag, the fragment names should be the same that they are inside the mobile_navigation.xml
:
<groupandroid:checkableBehavior="single"><itemandroid:id="@+id/homeFragment"android:icon="@drawable/ic_menu_camera"android:title="@string/menu_home" /><itemandroid:id="@+id/galleryFragment"android:icon="@drawable/ic_menu_gallery"android:title="@string/menu_gallery" /><itemandroid:id="@+id/slideshowFragment"android:icon="@drawable/ic_menu_slideshow"android:title="@string/menu_slideshow" /><itemandroid:id="@+id/toolsFragment"android:icon="@drawable/ic_menu_manage"android:title="@string/menu_tools" /></group><itemandroid:title="Communicate"><menu><itemandroid:id="@+id/shareFragment"android:icon="@drawable/ic_menu_share"android:title="@string/menu_share" /><itemandroid:id="@+id/sendFragment"android:icon="@drawable/ic_menu_send"android:title="@string/menu_send" /></menu></item></menu>
This way, with what is going to be explained below there will be no need to call for onCreateOptionsMenu
to detect the clicks. Android team has already solved that for us. Follow below.
Until now, this doesn't differ too much from the usual drawer set up we actually do. But, there are some configurations we would need to do in the logic part of the app. So let's open MainActivity.kt
. First you will need these:
privatevar appBarConfiguration: AppBarConfiguration? = nullprivatevar drawerLayout: DrawerLayout? = nullprivatevar toolbar: Toolbar? = nullprivatevar navController: NavController? = null
After that in your onCreate
method:
overridefunonCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
toolbar = findViewById(R.id.toolbar)
setSupportActionBar(toolbar) //set the toolbar
drawerLayout = findViewById(R.id.drawer_layout)
val navView: NavigationView = findViewById(R.id.nav_view)
navController = findNavController(R.id.nav_host_fragment)
appBarConfiguration = AppBarConfiguration(
setOf(
R.id.homeFragment,
R.id.galleryFragment,
R.id.slideShowFragment,
R.id.toolsFragment,
R.id.shareFragment,
R.id.sendFragment,
R.id.loginFragment,
R.id.phoneConfirmationFragment
), drawerLayout
)
setupActionBarWithNavController(navController!!, appBarConfiguration!!) //the most important part
navView.setupWithNavController(navController!!) //the second most important part//other things unrelated
}
Let's see what's going on here:
First you would need a reference to the navController
. The AppBarConfiguration
is just a class which holds the fragments that are going to be opened as top level destinations. Which means that the fragment which is going to be opened after them would release the current one from the fragment back stack. It's important to tell to the AppBarConfiguration
that we have a drawer also (passed as a parameter in the constructor).
Down below you would have a method called onSupportNavigateUp()
:
overridefunonSupportNavigateUp(): Boolean {
val navController = findNavController(R.id.nav_host_fragment)
return navController.navigateUp(appBarConfiguration!!) || super.onSupportNavigateUp()
}
This method has to do with the up back button. But you won't need it too much if you have drawer navigation. This really comes in handy when you have a lot of fragments added on the backstack (or at least two).
Can everything be done with one Activity?
Yes, definitely! but still it requires a little bit more work when it comes to conditional navigation. Like when you want to show fragments which are not part of your drawer app. But still Google has done a huge progress with it. You can refer to conditional navigation here.
How do I handle toolbar visibility with just one Activity and fragments which have a dynamic toolbar visibility. Also, there are fragments which I need to close the drawer and make it inaccessible.
You can use addOnDestinationChangedListener
from the navController
:
navController.addOnDestinationChangedListener { _, destination, _ ->when (destination.id) {
R.id.loginFragment, R.id.registerFragment, R.id.phoneConfirmationFragment -> {
toolbar?.visibility = View.GONE
drawerLayout?.setDrawerLockMode(DrawerLayout.LOCK_MODE_LOCKED_CLOSED)
}
else-> {
toolbar?.visibility = View.VISIBLE
drawerLayout?.setDrawerLockMode(DrawerLayout.LOCK_MODE_UNLOCKED)
}
}
}
Now you have a drawer and navigation component on your app.
Post a Comment for "How To Set Up Navigation Component With Navigation Drawer In Android?"