1

I did take a look on the official website Nested Graph and searched related issues but have no luck on it.

When the nest graph and dynamic feature module comes up, I tried to combine "dynamic feature module", "Nested NavHostFragments" and "Nested Graph" into a separate module. But when I tried to handle the back button event, I have no idea on it.

I have the NavHostFragments in the "app" module and when the user navigation the account item on the bottom navigation view. It will prompt up a bottomsheetdialog, which contains a nested NavHostFragment and also its navigation graph. And those fragments are inside "account" module.

When I tried to navigation back by pressing back button in the account page, it does not get back the stacks inside the nested NavHostFragment. This setPrimaryNavigationFragment() function seems providing some clue for this issue but i have no luck on it.

That's the current behavior

current_behavior

MainActivity.kt (In "app" module)

class MainActivity : AppCompatActivity() {
    private lateinit var toolbar: Toolbar
    private lateinit var appBarConfiguration: AppBarConfiguration
    private val navController: NavController by lazy {
        findNavController(R.id.nav_host_fragment)
    }
    private val listener =
        NavController.OnDestinationChangedListener { controller, destination, arguments ->
            model.triggerDestination(destinationId = destination.id)
        }

    private val model: MainActivityViewModel by viewModels()


    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)

        toolbar = findViewById(R.id.toolbar)
        setSupportActionBar(toolbar)

        val navView: BottomNavigationView = findViewById(R.id.nav_view)

        appBarConfiguration = AppBarConfiguration(
            setOf(
                R.id.navigation_explore
            )
        )

        setupActionBarWithNavController(navController, appBarConfiguration)
        navView.setupWithNavController(navController)

        model.notificationPageSelect.observe(this, EventObserver {
            when (it) {
                R.id.navigation_explore -> updateAppBarBg(R.drawable.explore_appbar_bg_gradient)
                R.id.navigation_notifications -> updateAppBarBg(R.drawable.notification_appbar_bg_gradient)
            }
        })
    }

    private fun updateAppBarBg(appBg: Int) {
        toolbar.setBackgroundResource(appBg)
    }

    override fun onCreateOptionsMenu(menu: Menu?): Boolean {
        menuInflater.inflate(R.menu.overflow_menu, menu)
        return super.onCreateOptionsMenu(menu)
    }

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

    override fun onResume() {
        super.onResume()
        navController.addOnDestinationChangedListener(listener)
    }

    override fun onPause() {
        super.onPause()
        navController.removeOnDestinationChangedListener(listener)
    }
}

activity_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:id="@+id/container"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <androidx.appcompat.widget.Toolbar
        android:id="@+id/toolbar"
        android:layout_width="0dp"
        android:layout_height="50dp"
        android:background="@drawable/explore_appbar_bg_gradient"
        android:theme="@style/ThemeOverlay.MaterialComponents.Dark.ActionBar"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent" />

    <androidx.coordinatorlayout.widget.CoordinatorLayout
        android:layout_width="0dp"
        android:layout_height="0dp"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toBottomOf="@+id/toolbar">
        <fragment
            android:id="@+id/nav_host_fragment"
            android:name="androidx.navigation.dynamicfeatures.fragment.DynamicNavHostFragment"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            app:defaultNavHost="true"
            app:layout_constraintBottom_toBottomOf="parent"
            app:layout_constraintLeft_toLeftOf="parent"
            app:layout_constraintRight_toRightOf="parent"
            app:layout_constraintTop_toBottomOf="@+id/toolbar"
            app:navGraph="@navigation/mobile_navigation" />

        <com.google.android.material.bottomnavigation.BottomNavigationView
            android:id="@+id/nav_view"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_marginStart="0dp"
            android:layout_marginEnd="0dp"
            android:background="?android:attr/windowBackground"
            app:labelVisibilityMode="labeled"
            app:layout_behavior="com.google.android.material.behavior.HideBottomViewOnScrollBehavior"
            app:menu="@menu/bottom_nav_menu"
            app:layout_anchorGravity="bottom|right|end"
            android:layout_gravity="bottom|end"
            />
    </androidx.coordinatorlayout.widget.CoordinatorLayout>



</androidx.constraintlayout.widget.ConstraintLayout>

AccountListDialogFragment.kt (in "account" module)

class AccountListDialogFragment : BottomSheetDialogFragment() {

    private lateinit var viewModel: SettingsViewModel

    override fun onCreateView(
        inflater: LayoutInflater, container: ViewGroup?,
        savedInstanceState: Bundle?
    ): View? = inflater.inflate(R.layout.fragment_account, container, false)

    override fun onActivityCreated(savedInstanceState: Bundle?) {
        super.onActivityCreated(savedInstanceState)
        viewModel = ViewModelProvider(this).get(SettingsViewModel::class.java)
    }

    override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
        setupFullExpand()
    }

}

fragment_account.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">


    <androidx.fragment.app.FragmentContainerView
        android: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_constraintBottom_toBottomOf="parent"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintRight_toRightOf="parent"
        app:layout_constraintTop_toTopOf="parent"
        app:navGraph="@navigation/account" />


</androidx.constraintlayout.widget.ConstraintLayout>
Long Ranger
  • 5,888
  • 8
  • 43
  • 72
  • https://github.com/android/architecture-components-samples/tree/master/NavigationAdvancedSample – denvercoder9 May 29 '20 at 05:11
  • The sample project did not use the nested NavHostFragments. Could you please explain why the link is related to my issue? – Long Ranger May 29 '20 at 08:43
  • If I understand correctly, you're looking for a solution for multiple back stack, right? If so, then that sample is useful. – denvercoder9 May 29 '20 at 08:46
  • Ok. My issue is about the nested NavHostFragments and the back event. I will take a look on it first. And thank you for the information. If it helps my issue, I will post the answer here. Otherwise, having the link without any explanation cannot help to solve the issue. – Long Ranger May 29 '20 at 08:54
  • 1
    In theory, you should have only 1 NavHostFragment. If you have to have a bottom navigation view available that retains the state of the stack as you navigate between them regardless of depth, then you can use the *hack* that you have N top-level NavHostFragments. I do not see why you would ever nest NavHostFragments, but surely you can do some magic tricks by registering a `BackPressDispatcher` on the host activity. – EpicPandaForce Jun 03 '20 at 06:01

0 Answers0