Background color change in BottomNavigationView
Try this it is a sample code of navigation item select listener. hope it helps you.
@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;
}
Alternative solution:
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.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/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.
Try this one.
found an answer from this medium post
- We need to use
android:state_checked
instead ofandroid:state_enabled
- within
onNavigationItemSelected
you need to usereturn true
instead ofreturn false
.
and to set background, we cannot use android:color
in <item>
, we need to use android:drawable
So here how it looks xml file when you are setting it for app:itemTextColor
and app:itemIconTint
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:color="@color/colorPrimaryDark" android:state_checked="true" />
<item android:color="@android:color/white" android:state_checked="false" />
</selector>
and to set app:itemBackground
selector
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:drawable="@drawable/banner_white" android:state_checked="true"/>
<item android:drawable="@drawable/banner_green" android:state_checked="false"/>
</selector>
Here banner_white
and banner_green
are pngs.
I encountered a similar problem to the OP's, but a little different. If you put sth like@color/color_selector
into the BottomNavigationView's app:itemBackground="___"
. It will cause the view to hide in design panel, and the app to crush when launching. Though it works fine if your just set it to a constant color like @color/black
.
For a more in-depth explanation, I dug into android api reference. Now I think I have found the answer that can reasonably resolve this problem. (May not accurate.)
The problem is, what you provide are NOT EXACTLY what they asked for.
app:itemIconTint
and app:itemTextColor
ask for a hex color, while app:itemBackground
asks for a literally Drawable. The <color>
elements we write in colors.xml
are ColorDrawable. It's derived from Drawable so it can feed all three attributes.
However, when you change it to use a selector, things become different. Both hex color and drawable have a corresponding selector. A selector acts like the resource you put in, but the outcome is not the original one. It's more like a single-purpose wrapper. You can't feed a hex color to an attribute who requires a Drawable.
The color selector is actually a ColorStateList, provides a hex color, resides in res/color
. You can use only the attribute android:color
in this file. it will prompt an error if you write android:drawable
.
The drawable selector is StateListDrawable, provides Drawable, resides in res/drawable
. You should write android:drawable
here, but there is no error if you write android:color
.
However android:color
only provides a hex color that can't be recognized as a Drawable, while app:itemBackground
requires a Drawable, so the app is doomed. (Direct cause)
Both attribute (android:color
and android:drawable
) accept a ColorDrawable, here it works just like when you set a constant color.
The solution (and the practice) is:
Use (and only)
android:drawable
in ares/drawable/drawable_selector.xml
. Example:<?xml version="1.0" encoding="utf-8"?> <selector xmlns:android="http://schemas.android.com/apk/res/android"> <item android:drawable="@color/colorAccent" android:state_checked="true" /> <item android:drawable="@color/colorAccentDark" /> </selector>
Use
res/color/color_selector.xml
when it needs a hex color (to avoid confusing). Example:<?xml version="1.0" encoding="utf-8"?> <selector xmlns:android="http://schemas.android.com/apk/res/android"> <item android:color="@android:color/white" android:state_checked="true"/> <item android:color="@color/colorPrimary" /> </selector>
Provide
app:itemBackground
with drawable. Example:<android.support.design.widget.BottomNavigationView ... app:itemBackground="@drawable/drawable_selector" app:itemIconTint="@color/color_selector" app:itemTextColor="@color/color_selector" ... />
(Worth noting that if you are using Android Studio, its auto-completion feature will tell you what attributes are legal and available, and it doesn't suggest you android:color
in a selector under res/drawable
!)