使用 android 导航组件时,有没有办法防止在 bottomNavigation 中重新创建片段

Is there a way to prevent re-create fragment in bottomNavigation when using android navigation component

我将底部导航与 android 导航组件一起使用 当我单击之前选择的项目时,系统会创建该片段的一个新实例,在视图中替换它并删除最后一个片段。 我想防止重新创建片段并忽略用户点击

这是我的菜单:

<item
    android:id="@+id/historyFragment"
    android:title="@string/main_records"
    android:icon="@drawable/ic_records"
    app:showAsAction="ifRoom"/>

<item
    android:id="@+id/mainFragment"
    android:icon="@drawable/ic_pulse"
    android:title="@string/main_measure" />

<item
    android:id="@+id/settingFragment"
    android:icon="@drawable/ic_settings"
    android:title="@string/main_setting"
    app:showAsAction="ifRoom"/>

从版本 2.2.0-alpha02 开始,这是一个已知问题,NavigationUI 不会开箱即用。但是,有一种 hacky 方法可以实现您想要的:

navController.addOnDestinationChangedListener { _, destination, _ ->

            for(menuItem in bottomNav.menu.iterator()){
                menuItem.isEnabled = true
            }

            val menu = bottomNav.menu.findItem(destination.id)
            menu?.isEnabled = false
}

在这里,如果 menuItem 的 ID 与目标 ID 相同,我将禁用它。但起初我启用了所有 menuItem,因为上一次迭代可能会禁用一个项目。

在此之后,要获得样式,您需要为禁用的 menuItem 设置颜色。您可以通过设置以下 colorState

来做到这一点
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
    <item
        android:state_checked="true"
        android:color="@color/colorPrimary" />
    <item
        android:state_checked="false"
        android:color="@color/colorAccent" />

    <item
        android:state_enabled="false"
        android:color="@color/colorPrimary" />
    <item
        android:state_enabled="true"
        android:color="@color/colorAccent" />
</selector>

最后你需要在 BottomNav 中使用这个颜色状态

<com.google.android.material.bottomnavigation.BottomNavigationView
        android:id="@+id/bottomNav"
        android:layout_height="wrap_content"
        android:layout_width="match_parent"
        app:itemIconTint="@color/bottom_color_state"
        app:itemTextColor="@color/bottom_color_state"
        app:menu="@menu/menu_bottom"/>

这不是最佳解决方案。但这行得通。

希望这对您有所帮助。