Android BottomNavigationView change icon focus color to accurately indicate fragment in view

Viewed 20

In my Android app (Java) I'm trying to figure out how to change my icon focus color to accurately indicate the fragment that is visible. If I press on a bottom nav icon, the icon I pressed is in focus and the navigation takes me to the fragment associated with that icon.

However, when I press the back arrow to go back to the home screen, the icon I previously pressed is still in focus instead of the home icon. How can I only have the icon associated with the visible fragment be in focus?

EDIT:

Here's my NavigationActivity xml:

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout 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:layout_width="match_parent"
    android:layout_height="match_parent"
    android:background="@drawable/background"
    tools:context=".activity.NavigationActivity">

    <androidx.appcompat.widget.Toolbar
        android:id="@+id/toolbar"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:theme="@style/ThemeOverlay.MaterialComponents.Dark.ActionBar" />


    <ImageView
        android:id="@+id/backArrow"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginStart="20dp"
        android:layout_marginTop="54dp"
        android:layout_marginBottom="20dp"
        android:src="@drawable/arrow_left"
        android:visibility="gone" />

    <ImageView
        android:id="@+id/logo"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_centerHorizontal="true"
        android:layout_marginStart="98dp"
        android:layout_marginTop="46dp"
        android:layout_marginBottom="20dp"
        android:layout_toEndOf="@+id/backArrow"
        android:src="@drawable/logo" />


    <fragment
        android:id="@+id/fragment"
        android:name="androidx.navigation.fragment.NavHostFragment"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:layout_above="@id/bottomBar"
        android:layout_below="@+id/logo"
        app:defaultNavHost="true"
        app:navGraph="@navigation/nav_graph" />

    <com.google.android.material.bottomnavigation.BottomNavigationView
        android:id="@+id/bottomBar"
        style="@style/BottomNavTheme"
        android:layout_width="match_parent"
        android:layout_height="70dp"
        android:layout_alignParentBottom="true"
        android:paddingTop="7dp"
        android:paddingBottom="7dp"
        android:theme="@style/app_theme"
        app:itemIconTint="@drawable/bottom_nav_icon_color_selector"
        app:itemTextColor="@drawable/bottom_nav_icon_color_selector"
        app:menu="@menu/bottom_bar_nav" />
</RelativeLayout>

Nav icon color selector xml:

<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
    <item android:state_checked="true" android:color="@android:color/white" />
    <item android:state_pressed="true" android:state_enabled="true" android:color="@android:color/white" />
    <item android:color="#8E8392" />
</selector> 

NavigationActivity:

@AndroidEntryPoint
public class NavigationActivity extends DeviceBaseActivity {
    NavController navController;
    private AppBarConfiguration appBarConfiguration;

    private ActivityNavigationBinding navigationBinding;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
        getWindow().getDecorView().setSystemUiVisibility(
                View.SYSTEM_UI_FLAG_LAYOUT_STABLE);
        navigationBinding = ActivityNavigationBinding.inflate(getLayoutInflater());
        View view = navigationBinding.getRoot();
        setContentView(view);

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

        navController = Navigation.findNavController(NavigationActivity.this, R.id.fragment);

        appBarConfiguration =
                new AppBarConfiguration.Builder(navController.getGraph()).build();

        setupActionBar(navController, appBarConfiguration);
        

        navigationBinding.bottomBar.setOnItemSelectedListener(new NavigationBarView.OnItemSelectedListener() {
            @Override
            public boolean onNavigationItemSelected(@NonNull MenuItem item) {
                switch (item.getItemId()) {
                    case R.id.mainFragment:
                        navController.navigate(R.id.mainFragment);
                        return true;
                    case R.id.scheduleFragment:
                        navController.navigate(R.id.scheduleFragment);
                        return true;
                    case R.id.settingsFragment:
                        navController.navigate(R.id.settingsFragment);
                        return true;
                }
                return false;
            }
        });

    }
    


    private void setupActionBar(NavController navController,
                                AppBarConfiguration appBarConfig) {

        NavigationUI.setupActionBarWithNavController(this, navController, appBarConfig);

    }


    @Override
    public boolean onSupportNavigateUp() {
        return NavigationUI.navigateUp(Navigation.findNavController(this, R.id.fragment), appBarConfiguration);
    }

}
1 Answers

No need to setOnItemSelectedListener, following is my setup:

1. Setup Menu Resource File

<menu 
    xmlns:android="http://schemas.android.com/apk/res/android">

    <item
        android:id="@+id/homeFragment"      //must match the id on navigation graph!!
        android:icon="@drawable/home"
        android:title="Home" />

    <item
        android:id="@+id/meFragment"        //must match the id on navigation graph!!
        android:icon="@drawable/person"
        android:title="Me" />

</menu>

2. Setup BottomNavigationView

<com.google.android.material.bottomnavigation.BottomNavigationView
    android:id="@+id/bottomNavigationView"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    app:menu="@menu/main" />

3. Setup MainActivity with BottomNavigationView

override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)
    binding = DataBindingUtil.setContentView(this, R.layout.activity_main)
    navController = getNavHostFragmentById(R.id.nav_host_fragment).navController

    NavigationUI.setupActionBarWithNavController(this, navController)
    NavigationUI.setupWithNavController(binding.bottomNavigationView, navController)        //key part
}

Demo: https://youtu.be/PSAbsVZz3Xw

Related