简体   繁体   中英

Stack Clear from dialog to fragment with navigation component

I am using the navigation component to do the navigation but the result is weird. When I tried to press back button from the dialog fragment(Cart). The current fragment stack graph (Home -> Notification) is clear, like the following.

导航视频

When I press the back button on Cart page,what I expected is to come back to the notification page, not the home page.

I didn't add any custom back press event in those fragments. It seems weird but I can't find any related documentation about it in the official.

Appreciate any comment or advice for this issue

here is my mobile-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/mobile_navigation"
    app:startDestination="@id/navigation_explore">

    <fragment
        android:id="@+id/navigation_explore"
        android:name="com.cn29.hkbvmall.ui.home.HomeFragment"
        tools:layout="@layout/fragment_explore" >
        <action
            android:id="@+id/action_navigation_explore_self"
            app:destination="@id/navigation_explore"
            app:enterAnim="@anim/slide_in_right"
            app:exitAnim="@anim/slide_out_left"
            app:popExitAnim="@anim/slide_out_right" />
        <argument
            android:name="activeCategoryId"
            app:argType="integer"
            android:defaultValue="0" />
    </fragment>

    <fragment
        android:id="@+id/navigation_notifications"
        android:name="com.cn29.hkbvmall.ui.notifications.NotificationsFragment"
        tools:layout="@layout/fragment_notifications" />
    <dialog
        android:id="@+id/navigation_mylist"
        android:name="com.cn29.hkbvmall.ui.mylist.MyListFragment"
        tools:layout="@layout/fragment_mylist" />
    <dialog
        android:id="@+id/navigation_cart"
        android:name="com.cn29.hkbvmall.ui.shoppingkart.GoodsListDialogFragment"
        android:label="GoodsListDialogFragment"
        tools:layout="@layout/fragment_shoppingkart"
        />

    <dialog
        app:moduleName="account"
        android:id="@+id/navigation_account"
        android:name="com.cn29.account.ui.AccountListDialogFragment"
        tools:layout="@layout/dynamic_feature_install_fragment"
    />
</navigation>

Here is my MainActivity.kt

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)
    }
}

If you look closely, you'll see that the home page is beeing shown just before the cart come up. This is due to the implementation of the BottomNavigationView.OnNavigationItemSelectedListener used with BottomNavigationView.setupWithNavController(NavController) .

It's just calling MenuItem.onNavDestinationSelected(NavController) , which pops the backstack to the start destination when the MenuItem is not having the secondary flag.

So whenever you don't want the stack to be cleared, you'll need to add android:menuCategory="secondary" to your menu item.

<item
    android:id="@+id/action_foo_bar"
    android:menuCategory="secondary"
    android:title="@string/action_foo_bar" />

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM