Change the color of a checked menu item in a navigation drawer
Well you can achieve this using Color State Resource. If you notice inside your NavigationView
you're using
app:itemIconTint="@color/black"app:itemTextColor="@color/primary_text"
Here instead of using @color/black
or @color/primary_test
, use a Color State List Resource
. For that, first create a new xml
(e.g drawer_item.xml) inside color
directory (which should be inside res
directory.) If you don't have a directory named color
already, create one.
Now inside drawer_item.xml
do something like this
<?xml version="1.0" encoding="utf-8"?><selector xmlns:android="http://schemas.android.com/apk/res/android"> <item android:color="checked state color" android:state_checked="true" /> <item android:color="your default color" /></selector>
Final step would be to change your NavigationView
<android.support.design.widget.NavigationView android:id="@+id/activity_main_navigationview" android:layout_width="wrap_content" android:layout_height="match_parent" android:layout_gravity="start" app:headerLayout="@layout/drawer_header" app:itemIconTint="@color/drawer_item" // notice here app:itemTextColor="@color/drawer_item" // and here app:itemBackground="@android:color/transparent"// and here for setting the background color to tranparent app:menu="@menu/menu_drawer">
Like this you can use separate Color State List Resources for IconTint
, ItemTextColor
, ItemBackground
.
Now when you set an item as checked (either in xml
or programmatically), the particular item will have different color than the unchecked ones.
I believe app:itemBackground
expects a drawable. So follow the steps below :
Make a drawable file highlight_color.xml
with following contents :
<shape xmlns:android="http://schemas.android.com/apk/res/android" android:shape="rectangle"> <solid android:color="YOUR HIGHLIGHT COLOR"/></shape>
Make another drawable file nav_item_drawable.xml
with following contents:
<selector xmlns:android="http://schemas.android.com/apk/res/android"> <item android:drawable="@drawable/highlight_color" android:state_checked="true"/></selector>
Finally add app:itemBackground
tag in the NavView :
<android.support.design.widget.NavigationViewandroid:id="@+id/activity_main_navigationview"android:layout_width="wrap_content"android:layout_height="match_parent"android:layout_gravity="start"app:headerLayout="@layout/drawer_header"app:itemIconTint="@color/black"app:itemTextColor="@color/primary_text"app:itemBackground="@drawable/nav_item_drawable"app:menu="@menu/menu_drawer">
here the highlight_color.xml file defines a solid color drawable for the background. Later this color drawable is assigned to nav_item_drawable.xml selector.
This worked for me. Hopefully this will help.
********************************************** UPDATED **********************************************
Though the above mentioned answer gives you fine control over some properties, but the way I am about to describe feels more SOLID and is a bit COOLER.
So what you can do is, you can define a ThemeOverlay in the styles.xml
for the NavigationView like this :
<style name="ThemeOverlay.AppCompat.navTheme"> <!-- Color of text and icon when SELECTED --> <item name="colorPrimary">@color/color_of_your_choice</item> <!-- Background color when SELECTED --> <item name="colorControlHighlight">@color/color_of_your_choice</item> </style>
now apply this ThemeOverlay to app:theme
attribute of NavigationView, like this:
<android.support.design.widget.NavigationViewandroid:id="@+id/activity_main_navigationview"android:layout_width="wrap_content"android:layout_height="match_parent"android:layout_gravity="start"app:theme="@style/ThemeOverlay.AppCompat.navTheme"app:headerLayout="@layout/drawer_header"app:menu="@menu/menu_drawer">
I hope this will help.
One need to set NavigateItem
checked true whenever item in NavigateView
is clicked
//listen for navigation eventsNavigationView navigationView = (NavigationView)findViewById(R.id.navigation);navigationView.setNavigationItemSelectedListener(this);// select the correct nav menu itemnavigationView.getMenu().findItem(mNavItemId).setChecked(true);
Add NavigationItemSelectedListener
on NavigationView
@Override public boolean onNavigationItemSelected(final MenuItem menuItem) { // update highlighted item in the navigation menu menuItem.setChecked(true); mNavItemId = menuItem.getItemId(); // allow some time after closing the drawer before performing real navigation // so the user can see what is happening mDrawerLayout.closeDrawer(GravityCompat.START); mDrawerActionHandler.postDelayed(new Runnable() { @Override public void run() { navigate(menuItem.getItemId()); } }, DRAWER_CLOSE_DELAY_MS); return true; }