android / architecture-components-samples

Samples for Android Architecture Components.
https://d.android.com/arch
Apache License 2.0
23.4k stars 8.29k forks source link

Control toolbar back button and hamburger icon from nested graph fragment in android #1004

Closed praveenshharma closed 3 years ago

praveenshharma commented 3 years ago

All of my drawer fragments are controlled through MainFragment, inside MainFragment a DrawerLayout is implemented which contains DashboardMainFragment, SettingFragment and PrivacyFragment. My requirement is to show Toolbar with menu into every child of drawer. So MainFragment looks like:

MainFragment.kt

        @AndroidEntryPoint
        class MainFragment :
        BaseFragment<FragmentMainBinding>(FragmentMainBinding::inflate) {

        private lateinit var appBarConfiguration: AppBarConfiguration
        private lateinit var drawerLayout: DrawerLayout
        private lateinit var navigationView: NavigationView
        private lateinit var navController: NavController

        override fun initViews() {
               drawerLayout = binding.drawerLayout
               navigationView = binding.navView
               val nestedNavHostFragment =
                    childFragmentManager.findFragmentById(R.id.nav_host_fragment_content_main) as? NavHostFragment
               navController = nestedNavHostFragment?.navController!!

      appBarConfiguration = AppBarConfiguration(
        setOf(
            R.id.navigation_dashboard, R.id.navigation_settings, R.id.navigation_privacy
        ), drawerLayout
    )
              NavigationUI.setupWithNavController(
              binding.appBarNav.toolbar,
              navController,
              appBarConfiguration
             )
             navigationView.setupWithNavController(navController)
             inflateMenuInToolbar()
         }

         override fun onCreate(savedInstanceState: Bundle?) {
         super.onCreate(savedInstanceState)
          setHasOptionsMenu(true)
       }

         private fun inflateMenuInToolbar() {
          binding.appBarNav.toolbar.inflateMenu(R.menu.dashboard_menu)
         }

         fun clearToolbarMenu() {
          binding.appBarNav.toolbar.menu.clear()
            }

fragment_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:id="@+id/drawer_layout"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fitsSystemWindows="true"
tools:openDrawer="start">

<include
    android:id="@+id/app_bar_nav"
    layout="@layout/content_main"
    android:layout_width="match_parent"
    android:layout_height="match_parent" />

<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"
    app:headerLayout="@layout/nav_header_nav"
    app:menu="@menu/drawer_nav_menu" />
</androidx.drawerlayout.widget.DrawerLayout>

content_main.xml

<?xml version="1.0" encoding="utf-8"?>
<androidx.coordinatorlayout.widget.CoordinatorLayout 
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">

<com.google.android.material.appbar.AppBarLayout
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:theme="@style/Theme.Shopingo.AppBarOverlay">

    <com.google.android.material.appbar.MaterialToolbar
        android:id="@+id/toolbar"
        android:layout_width="match_parent"
        android:layout_height="?attr/actionBarSize"
        android:background="?attr/colorPrimary"
        app:popupTheme="@style/Theme.Shopingo.PopupOverlay" />

</com.google.android.material.appbar.AppBarLayout>

<androidx.constraintlayout.widget.ConstraintLayout
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    app:layout_behavior="@string/appbar_scrolling_view_behavior"
    tools:showIn="@layout/app_bar_nav">

    <androidx.fragment.app.FragmentContainerView
        android:id="@+id/nav_host_fragment_content_main"
        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/drawer_navigation" />

 </androidx.constraintlayout.widget.ConstraintLayout>
</androidx.coordinatorlayout.widget.CoordinatorLayout>

drawer_navigation.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"
 android:id="@+id/mobile_navigation2"
 app:startDestination="@+id/navigation_dashboard">

<fragment
    android:id="@+id/navigation_dashboard"
    android:name="com.next.shopingo.ui.fragments.main.home.drawer.DashboardMainFragment"
    android:label="Dashboard" />

<fragment
    android:id="@+id/navigation_settings"
    android:name="com.next.shopingo.ui.fragments.main.home.drawer.SettingsFragment"
    android:label="Settings" />

<fragment
    android:id="@+id/navigation_privacy"
    android:name="com.next.shopingo.ui.fragments.main.home.drawer.PrivacyFragment"
    android:label="Privacy Policy" />
  </navigation>

fragment_dashboard_main.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"
  android:layout_width="match_parent"
  android:layout_height="match_parent"
  app:layout_behavior="@string/appbar_scrolling_view_behavior">

<androidx.fragment.app.FragmentContainerView
    android:id="@+id/nav_host_fragment_dashboard_main"
    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/dashboard_navigation" />
   </androidx.constraintlayout.widget.ConstraintLayout>

dashboard_navigation.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/dashboard_navigation"
   app:startDestination="@id/dashboardFragment">
    <fragment
    android:id="@+id/dashboardFragment"
    android:name="com.next.shopingo.ui.fragments.main.home.dashboard.DashboardFragment"
    android:label="Dashboard Content"
    tools:layout="@layout/fragment_dashboard">
    <action
        android:id="@+id/dashboard_frag_to_detail_frag"
        app:destination="@id/detailFragment" />
</fragment>
<fragment
    android:id="@+id/detailFragment"
    android:name="com.next.shopingo.ui.fragments.main.home.dashboard.DetailFragment"
    android:label="Detail"
    tools:layout="@layout/fragment_detail" />

        </navigation>

Now stack management working fine like switching between Drawer Parent fragments(DashboardMain, Settings, Privacy). Now when I add nested graph in DashboardMainFragment which contains fragments like DashboardFragment, DashboardDetailFragment and navigate from DashboardFragment to DashboardDetailFragment, toolbar doesn't show back button automatically. It still displays hamburger icon.

My Question is, Is there any way in Jetpack Navigation so that toolbar can automatically take ownership of showing back button and also handles the nav controller for nested graphs and parent one.

praveenshharma commented 3 years ago

@ianhanniballake Can you post an answer how to handle toolbar(placed in drawer with appbarconfiguration) from nested graph (contains by drawer fragment) ?

ianhanniballake commented 3 years ago

The architecture-component-samples issues list is for issues with the samples only; this isn't the appropriate place for issues with a specific library (that would be for the official issue tracker) or about your own code (where stackoverflow would be a better choice).