Search code examples
javaandroidbottomnavigationviewandroid-architecture-navigation

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


I'm using bottom navigation with the android navigation component when I clicked on an item that is selected before, the system creates a new instance of that fragment, replace that on view and remove the last fragment. I want to prevent re-creating fragments and ignore user clicking

this is my menu:

<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"/>


Solution

  • As of Version 2.2.0-alpha02 this is a known issue and NavigationUI does not check this out of the box. However, there is a hacky way to achieve what you wanted:

    navController.addOnDestinationChangedListener { _, destination, _ ->
    
                for(menuItem in bottomNav.menu.iterator()){
                    menuItem.isEnabled = true
                }
    
                val menu = bottomNav.menu.findItem(destination.id)
                menu?.isEnabled = false
    }
    

    Here, I am disabling the menuItem if it's id is the same to the destination id. But at first I am enabling all the menuItem as one item might be disabled by previous iteration.

    After this, to get the style you need to set a color to the disabled menuItem. You can do this by setting following 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>
    

    Finally you need to use this color state in the 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"/>
    

    This is not the best solution. But this would work.

    Hope, this would help you.