Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to use Navigation Drawer and Bottom Navigation simultaneously - Navigation Architecture Component

Tags:

I have screen like below which contain a navigation drawer and bottom navigation on same screen:

app screen

I am using Jetpack Navigation Architecture Component.

Current issue and What I have tried?

Clicking on the 2nd and 3rd bottom nav item shows back arrow on toolbar?

Tried: setting fragments associated with 2nd and 3rd bottom nav to top level destinations

appBarConfig = AppBarConfiguration(setOf(R.layout.fragment_star, R.layout.fragment_stats, R.layout.fragment_user)) 

instead of

appBarConfig = AppBarConfiguration(navController.graph, drawerLayout) 

Did not worked.

Any help highly appreciated!


My code look like below.

activity_main.xml

<?xml version="1.0" encoding="utf-8"?> <layout     xmlns:android="http://schemas.android.com/apk/res/android"     xmlns:app="http://schemas.android.com/apk/res-auto">      <androidx.drawerlayout.widget.DrawerLayout         android:id="@+id/drawerLayout"         android:layout_width="match_parent"         android:layout_height="match_parent"         android:fitsSystemWindows="true">           <LinearLayout             android:layout_width="match_parent"             android:layout_height="match_parent"             android:orientation="vertical">              <androidx.appcompat.widget.Toolbar                 android:id="@+id/toolbar"                 android:layout_width="match_parent"                 android:layout_height="?attr/actionBarSize"                 android:background="?attr/colorPrimary"                 app:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar"/>              <fragment                 android:id="@+id/navHostFragment"                 android:name="androidx.navigation.fragment.NavHostFragment"                 android:layout_width="match_parent"                 android:layout_height="0dp"                 android:layout_weight="1"                 app:defaultNavHost="true"                 app:navGraph="@navigation/nav_graph" />              <com.google.android.material.bottomnavigation.BottomNavigationView                 android:id="@+id/bottomNav"                 android:layout_width="match_parent"                 android:layout_height="wrap_content"                 android:layout_gravity="bottom"                 android:background="?android:attr/windowBackground"                 app:menu="@menu/menu_bottom" />          </LinearLayout>          <!-- gives navDrawer material look-->         <com.google.android.material.navigation.NavigationView             android:id="@+id/navView"             android:layout_width="wrap_content"             android:layout_height="match_parent"             android:layout_gravity="start"             app:menu="@menu/nav_drawer_menu"             app:headerLayout="@layout/nav_header"             android:fitsSystemWindows="true"             />     </androidx.drawerlayout.widget.DrawerLayout> </layout> 

menu_bottom.xml

<?xml version="1.0" encoding="utf-8"?> <menu xmlns:android="http://schemas.android.com/apk/res/android">      <item         android:id="@+id/starFragment"         android:icon="@drawable/ic_star_green_48dp"         android:title="@string/bottom_nav_title_star"/>      <item         android:id="@+id/statsFragment"         android:icon="@drawable/ic_stats_green_48dp"         android:title="@string/bottom_nav_title_stats"/>      <item         android:id="@+id/userFragment"         android:icon="@drawable/ic_user_green_48dp"         android:title="@string/bottom_nav_title_user"/>  </menu> 

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_main"             app:startDestination="@id/starFragment">      <fragment         android:id="@+id/starFragment"         android:name="com.example.app.ui.StarrFragment"         android:label="Star"         tools:layout="@layout/fragment_star">     </fragment>     <fragment         android:id="@+id/statsFragment"         android:name="com.example.app.StatsFragment"         android:label="fragment_stats"         tools:layout="@layout/fragment_stats" />     <fragment         android:id="@+id/userFragment"         android:name="com.example.app.UserFragment"         android:label="fragment_user"         tools:layout="@layout/fragment_user" /> </navigation> 

ActivityMain.kt

class MainActivity : AppCompatActivity() {      private lateinit var drawerLayout: DrawerLayout     private lateinit var appBarConfig: AppBarConfiguration     private lateinit var navController: NavController      override fun onCreate(savedInstanceState: Bundle?) {         super.onCreate(savedInstanceState)          val binding = DataBindingUtil.setContentView<ActivityMainBinding>(this, R.layout.activity_main)         setSupportActionBar(toolbar)          drawerLayout = binding.drawerLayout         navController = this.findNavController(R.id.navHostFragment)          binding.bottomNav.setupWithNavController(navController)          NavigationUI.setupActionBarWithNavController(this, navController, drawerLayout)         appBarConfig = AppBarConfiguration(navController.graph, drawerLayout)           // lock drawer when not in start destination         navController.addOnDestinationChangedListener { nc, nd, _ ->              if(nd.id == nc.graph.startDestination){                 drawerLayout.setDrawerLockMode(DrawerLayout.LOCK_MODE_UNLOCKED)             }             else{                 drawerLayout.setDrawerLockMode(DrawerLayout.LOCK_MODE_LOCKED_CLOSED)             }         }           NavigationUI.setupWithNavController(binding.navView, navController)     }      override fun onSupportNavigateUp(): Boolean {          // replace navigation up button with nav drawer button when on start destination         return NavigationUI.navigateUp(navController, appBarConfig)      } } 
like image 462
user158 Avatar asked May 05 '19 10:05

user158


People also ask

How do I use the same navigation drawer in all activities?

Navigation drawers are the most common use android widget in android. The user can view the navigation drawer when they swipe the activity's screen from the left edge of the android device. A user can also find it from the activity, by tapping the app icon (also known as the “hamburger” menu) in the action bar.

Which view is used to add the navigation drawer to an app?

Step 3 -Setup NavigationView NavigationView is an easy way to display a navigation menu from a menu resource. This is most commonly used in conjunction with DrawerLayout to implement Material navigation drawers.


2 Answers

No need of writing separate code to replace the back button with the drawer icon.

In AppBarConfiguration pass the fragment ids (from nav_graph) which you are using to navigate from both bottom navigation & navigation drawer. (P.S fragments and its associated icon should have same ids)

For your case the AppBarConfiguration should look like this :

appBarConfig = AppBarConfiguration.Builder(R.id.starFragment, R.id.statsFragment, R.id.userFragment)                 .setDrawerLayout(drawerLayout)                 .build() 

Setup the action bar :

setSupportActionBar(toolbar) setupActionBarWithNavController(navController, appBarConfig) 

Now setup navcontroller for both bottom navigation & navigation view :

navView.setupWithNavController(navController) bottomNav.setupWithNavController(navController) 

onSupportNavigateUp function should should be :

override fun onSupportNavigateUp(): Boolean {         return navController.navigateUp(appBarConfig)     } 

Back button press should be handled if drawer is open :

override fun onBackPressed() {         if (drawerLayout.isDrawerOpen(GravityCompat.START)) {             drawerLayout.closeDrawer(GravityCompat.START)         } else {             super.onBackPressed()         }     } 

Bonus

By default when you click bottom navigation icon in the order icon_1 then icon_2 then icon_3 and from there you press back button it will navigate back to home icon that's icon_1

If you want to navigate back in the reverse order in which you have clicked the icons (back stack manner) then add android:menuCategory="secondary" to the item in the menu. So your menu will be like :

<menu xmlns:android="http://schemas.android.com/apk/res/android">     <item         android:id="@+id/starFragment"         android:icon="@drawable/ic_star_green_48dp"         android:title="@string/bottom_nav_title_star"         android:menuCategory="secondary"/>     <item         android:id="@+id/statsFragment"         android:icon="@drawable/ic_stats_green_48dp"         android:title="@string/bottom_nav_title_stats"         android:menuCategory="secondary"/>     <item         android:id="@+id/userFragment"         android:icon="@drawable/ic_user_green_48dp"         android:title="@string/bottom_nav_title_user"         android:menuCategory="secondary"/> </menu> 

Hope the back button icon will be solved now :)

like image 64
Atr07 Avatar answered Oct 03 '22 20:10

Atr07


This project uses DrawerLayout and simulates BottomNavigationView using RadioButtons, this is the way I found to solve the problem


In the Google Codelab navigation project they do what Adithya T Raj mention but it only serves to show the DrawerLayout on landscape and BottomNavigationView on Portrait. The project link:

I try to force them to show me both on this branch but only the DrawerLayout is shown

like image 23
evaldez Avatar answered Oct 03 '22 21:10

evaldez