如何在Android Navigation组件中管理BottomNavigationView返回栈

10
我正在使用导航组件和 BottomNavigationView,遇到一个问题:当我从 fragment 1 跳转到 2、5、4、3 时,按下返回按钮后会回到 fragment 1。我知道这是默认行为,但我不想这样,我想将它们保存在 backstack 中,这样当我按下返回按钮时,它应该返回到 fragment 4 而不是 1。我一直在尝试和搜索,但找不到任何解决方案。我能否在 Kotlin 中手动将 fragment 放入 backstack?
我的代码:
activity_main.xml
<androidx.constraintlayout.widget.ConstraintLayout
           .......................
           .......................>

            <androidx.appcompat.widget.Toolbar
               ................
               ................/>

            <fragment
                android:id="@+id/app_nav_host_fragment"
                android:name="androidx.navigation.fragment.NavHostFragment"
                android:layout_width="0dp"
                android:layout_height="0dp"
                app:defaultNavHost="true"
                app:navGraph="@navigation/app_nav"
                ..............
                ............../>
            <com.google.android.material.bottomnavigation.BottomNavigationView
                android:id="@+id/app_bottom_nav_view"
                android:layout_width="0dp"
                android:layout_height="wrap_content"
                android:background="@drawable/white_grey_border_bottom"
                app:menu="@menu/bottom_nav_menu"
                app:labelVisibilityMode="unlabeled"
                ...........
                .........../>

</androidx.constraintlayout.widget.ConstraintLayout>

app_nav.xml

<navigation 
    ...........
    ...........
    android:id="@+id/app_nav"
    app:startDestination="@id/homeFragment">

    <fragment
        android:id="@+id/homeFragment"
        android:name="com.example.instagram_clone.ui.HomeFragment"
        android:label="HomeFragment"
        tools:layout="@layout/fragment_home"/>
    .............
    .............
    .............
    .............
</navigation>

MainActivity.kt

class MainActivity : AppCompatActivity()
{
    override fun onCreate(savedInstanceState: Bundle?)
    {
        super.onCreate(savedInstanceState)

        val binding  = DataBindingUtil.setContentView<ActivityMainBinding>(this, R.layout.activity_main)
        val bottomNavView = binding.appBottomNavView
        val navController = findNavController(R.id.app_nav_host_fragment)

        bottomNavView.setupWithNavController(navController)

    }
}
1个回答

21
根据onNavDestinationSelected()文档(setupWithNavController()在选择菜单项时使用的方法):
默认情况下,返回栈将弹回导航图的起始目标。 具有android:menuCategory="secondary"的菜单项将不会弹出返回栈。
因此,只需将android:menuCategory="secondary"添加到与BottomNavigationView一起使用的每个菜单项即可。

1
在调用 setupWithNavController 后,您需要设置自己的 OnNavigationItemSelectedListener 并进行自己的 navigate() 调用,添加 NavOptions 对象并使用 setPopUpTo 将其设置为与您要导航到的相同目标,遵循与 onNavDestinationSelected() 的代码背后相同的模式 - 没有内置的辅助程序来实现该行为。 - ianhanniballake
2
我目前遇到的问题是没有弹出任何内容(使用默认设置)。如果我导航 1 > 2 > 3,然后按返回键,我会回到 2。(在 2.1.0 版本上) - cwiesner
2
@cwiesner - 听起来你弹出了图形的起始目标。你不应该这样做(请参阅导航原则文档和有关条件导航的文档)。 - ianhanniballake
4
@ianhanniballake 我的起始目标是启动画面,我使用底部导航从启动画面导航到这个屏幕。因此,如果我不弹出我的起始目标,启动画面将一直存在。那么,处理这个问题的最佳实践是什么? - Saman Sattari
1
@Askani 这里是如何将已经在后退栈中的片段避免再次放置进去的方法:https://dev59.com/c8Hqa4cB1Zd3GeqP6sKb#68779398 - NickUnuchek
显示剩余3条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接