0

I'm trying to change the text color of the selected item in the NavigationView. Using the information for the previous topic I set a selector:

<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
    <item android:color="@color/primaryColor" android:state_checked="true" />
    <item android:color="@color/lightGrayColor" android:state_checked="false" />
</selector>

The primaryColor is blue. The NavigationView is as follows:

    <com.google.android.material.navigation.NavigationView
        android:id="@+id/nav_view"
        android:layout_width="wrap_content"
        android:layout_height="match_parent"
        android:layout_gravity="start"
        app:headerLayout="@layout/activity_nav_header"
        app:menu="@menu/nev_menu"
        app:itemIconTint="@drawable/menu_item_selector"
        app:itemTextColor="@drawable/menu_item_selector" />

</androidx.drawerlayout.widget.DrawerLayout>

As you can see I set app:itemTextColor to menu_item_selector. But when I run the application, I see the selected item as grey. How does the NavigationView know which screen am I seeing right now? How do I fix it?

I'm using onNavigationItemSelected to switch between activities. Also I currently have only two windows - the dashboard and the logout. From the main screen I move to the dashboard (which contains the menu) and using the logout I go back to the main screen. Maybe the reason for it not working is because it does not know that the current screen is dashboard?

The dashboard java cotnains the following method:

    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_dashboard);

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

        drawerLayout = findViewById(R.id.drawer_layout);
        navigationView = findViewById(R.id.nav_view);

        ActionBarDrawerToggle toggle = new ActionBarDrawerToggle(this, drawerLayout, toolBar,
                R.string.navigation_drawer_open, R.string.navigation_drawer_close);
        drawerLayout.addDrawerListener(toggle);
        toggle.syncState();

        NavigationView navigationView = (NavigationView) findViewById(R.id.nav_view);
        navigationView.setNavigationItemSelectedListener(this);
        View hView = navigationView.getHeaderView(0);
    }

   @Override
    public boolean onNavigationItemSelected(@NonNull MenuItem item) {
        switch (item.getItemId()) {
            case R.id.dashboard:
                // CURRENT ACTIVITY
                break;
            case R.id.messages:
                startActivity(new Intent(this, MessagesActivity.class));
                break;
            case R.id.settings:
                startActivity(new Intent(this, SettingsActivity.class));
                break;
            case R.id.about:
                startActivity(new Intent(this, AboutActivity.class));
                break;
            case R.id.logout:
                startActivity(new Intent(this, MainActivity.class));
                break;
        }

        drawerLayout.closeDrawer(GravityCompat.START);
        return true;
    }
vesii
  • 2,760
  • 4
  • 25
  • 71

1 Answers1

0

For the initial look, you set a checked color to primaryColor, but overwrite it with lightGrayColor as you didn't specify the state that this color is available at; so you need to specify the state by android:state_checked="false"

<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
    <item android:color="@color/primaryColor" android:state_checked="true" />
    <item android:color="@color/lightGrayColor" android:state_checked="false"/>
</selector>

You can also set the default selected item at the app start by trying any of:

navigationView.getMenu().getItem(0).setChecked(true);
navigationView.setCheckedItem(R.id.nav_item);

Update

This is how it works with me

Step 1: Use the same selector:

selector.xml

<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
    <item android:color="@color/primaryColor" android:state_checked="true" />
    <item android:color="@color/lightGrayColor" android:state_checked="false" />
</selector>

Step 2: use the xml attribute app:itemTextColor within NavigationView widget

<android.support.design.widget.NavigationView
    android:id="@+id/nav_view"
    android:layout_width="wrap_content"
    android:layout_height="match_parent"
    android:layout_gravity="start"
    app:headerLayout="@layout/navigation_header_layout"
    app:itemTextColor="@drawable/selector"
    app:menu="@menu/navigation_menu" />

Step 3:
The previous step attribute won't work automatically as for some reason when you hit an item from the NavigationView menu, it doesn't consider this as a button check. So you need to manually get the selected item checked and clear the previously selected item. Use below listener to do that

@Override
public boolean onNavigationItemSelected(@NonNull MenuItem item) {

    int id = item.getItemId();

    // remove all colors of the items to the `unchecked` state of the selector
    removeColor(mNavigationView);

    // check the selected item to change its color set by the `checked` state of the selector
    item.setChecked(true);

    switch (item.getItemId()) {
      case R.id.dashboard:
            // CURRENT ACTIVITY
            break;
        case R.id.messages:
            startActivity(new Intent(this, MessagesActivity.class));
            break;
        case R.id.settings:
            startActivity(new Intent(this, SettingsActivity.class));
            break;
        case R.id.about:
            startActivity(new Intent(this, AboutActivity.class));
            break;
        case R.id.logout:
            startActivity(new Intent(this, MainActivity.class));
            break;
    }

    drawerLayout.closeDrawer(GravityCompat.START);
    return true;
}

private void removeColor(NavigationView view) {
    for (int i = 0; i < view.getMenu().size(); i++) {
        MenuItem item = view.getMenu().getItem(i);
        item.setChecked(false);
    }
}

Now the text color will change perfectly.

Step 4:
To change icon colors, use the app:iconTint attribute in the NavigationView menu items, and set to the same selector.

<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto">
    <item
        android:id="@+id/nav_account"
        android:checked="true"
        android:icon="@drawable/ic_person_black_24dp"
        android:title="My Account"
        app:iconTint="@drawable/selector" />
    <item
        android:id="@+id/nav_settings"
        android:icon="@drawable/ic_settings_black_24dp"
        android:title="Settings"
        app:iconTint="@drawable/selector" />

    <item
        android:id="@+id/nav_logout"
        android:icon="@drawable/logout"
        android:title="Log Out"
        app:iconTint="@drawable/selector" />
</menu>

Result:

Zain
  • 37,492
  • 7
  • 60
  • 84
  • The first solution didn't work for me. I also tried to change the colors in order to see if the selector is being used at all and it's being used. I prefer not to set it using Java, rather using the XML option. – vesii May 13 '20 at 22:51