Change background color Bottom Bar android - android

I have a problem in my Android project.
I can't change the color of the bottombar.
This is how I want my bottombar to look:
This is my code
menu > tabhost_bottom.xml
<menu xmlns:android="http://schemas.android.com/apk/res/android"
>
<item
android:id="#+id/home_item"
android:icon="#drawable/ic_home"
android:color="#color/colorPrimary"
android:title="Home"
/>
<item
android:id="#+id/setting_item"
android:icon="#drawable/ic_setting"
android:color="#color/colorPrimary"
android:title="Setting" />
HomeActivity.java
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_home);
coordinatorLayout = (CoordinatorLayout) findViewById(R.id.tabhost_activity);
BottomBar bottomBar = BottomBar.attach(this, savedInstanceState);
bottomBar.setItemsFromMenu(R.menu.tabhost_bottom, new OnMenuTabSelectedListener() {
#Override
public void onMenuItemSelected(int itemId) {
}
});
// Set the color for the active tab. Ignored on mobile when there are more than three tabs.
bottomBar.setActiveTabColor("#55a8e5");
// Use the dark theme. Ignored on mobile when there are more than three tabs.
bottomBar.setBackgroundColor(Color.parseColor("#55a8e5"));
// Use custom text appearance in tab titles.
//bottomBar.setTextAppearance(R.style.MyTextAppearance);
// Use custom typeface that's located at the "/src/main/assets" directory. If using with
// custom text appearance, set the text appearance first.
//bottomBar.setTypeFace("MyFont.ttf");
}
and this my reference
http://androidgifts.com/build-android-material-design-bottom-navigation/

I've finally achieved to change it with the following code (Xamarin C#)
var bottomBarBackground = FindViewById(Resource.Id.bb_bottom_bar_background_view);
bottomBarBackground.SetBackgroundResource(Resource.Drawable.tabbar_background);
tabbar_background.axml:
<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android" >
<item>
<shape android:shape="rectangle">
<solid android:color="#color/YourColor"/>
</shape>
</item>
</layer-list>
Found also here, though the final solution did not work for me with the Xamarin version: Question about background color

Is this the library?
Other Option:
seems like you need to set the Background color a different way:
// Setting colors for different tabs when there's more than three of them.
// You can set colors for tabs in three different ways as shown below.
mBottomBar.mapColorForTab(0, ContextCompat.getColor(this, R.color.colorAccent));
mBottomBar.mapColorForTab(1, 0xFF5D4037);
mBottomBar.mapColorForTab(2, "#7B1FA2");
mBottomBar.mapColorForTab(3, "#FF5252");
mBottomBar.mapColorForTab(4, "#FF9800");
For more inforation:
Android new Bottom Navigation bar

For all Kotlin fans: To set background color for all items in bottom bavigation bar, just add this lines in class MainActivity function onCreate:
// finds view in bottom_nav_menu.xml
val navView: BottomNavigationView = findViewById(R.id.nav_view)
// sets background color for the whole bar
navView.setBackgroundColor(ContextCompat.getColor(this, R.color.yourColor))

When you are using this library (roughike's bottombar) you can try this.
You can set the backgroundcolor of a specific tab by using the following line:
bottomBar.getTabAtPosition(0).setBackgroundColor(backgroundColorInt);
When you use this line multiple times for each tab, you can change the backgroundcolor of the whole tab.

Related

Android one shape resource file for different buttons

I've got a 5 buttons. They have a similar corners radius but different background color. Can i make one shape for radius and change buttons color with xml resources? So, main problem is set background color for them. I can't use android:background attribute twice. I thought about style, but in the syles i also need to set thia attribute twice. Is t possible to make only 1 shape file, or should create own file for each button?
here's what works:
shape.xml:
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android">
<corners android:radius="5dp"/>
<solid android:color="#0f0"/>
</shape>
and in onCreate in your java code:
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Button b=(Button)findViewById(R.id.button);
b.setBackgroundColor(Color.BLUE);
}
im Glad if i helped:)

Android AlertDialog text selection icon color

I have a problem when selecting the text inside an EditText control inside an AlertDialog.
When I select the text, the text selection toolbar shows up at the top of the screen. The problem is that the toolbar background is white, and the icons displayed in the toolbar are also white. Therefore, the icons are not visible (but they work if you touch them). This is on Android 4.2.2 (API 17).
This is the snippet of code I use to create the AlertDialog that contains the EditText. It is located in the onCreate method of my test project's activity.
EditText et = new EditText(this);
et.setText("Test");
AlertDialog.Builder b = new AlertDialog.Builder(this);
b.setView(et).setPositiveButton("Ok", null).setNegativeButton("Cancel", null);
b.create().show();
Here is how the text selection toolbar looks when the text is selected:
How can I change the color of the toolbar and/or icons so that they will be visible?
I think you can use:
<item name="actionModeBackground">#drawable/background</item>
<item name="android:actionModeBackground">#drawable/background</item>
in your main theme. I'm not sure you can point at colors rather than at drawable. A quick workaround is defining a shape drawable. To be more precise you could have a drawable/background.xml like:
<?xml version="1.0" encoding="utf-8"?>
<shape
xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle" >
<solid
android:color="#color/color" />
</shape>

Changing the background drawable of the searchview widget

I'm trying to change the drawable that sits in the Android actionbar searchview widget.
Currently it looks like this:
but I need to change the blue background drawable to a red colour.
I've tried many things short of rolling my own search widget, but nothing seems to work.
Can somebody point me in the right direction to changing this?
Intro
Unfortunately there's no way to set SearchView text field style using themes, styles and inheritance in XML as you can do with background of items in ActionBar dropdown. This is because selectableItemBackground is listed as styleable in R.stylable, whereas searchViewTextField (theme attribute that we're interested in) is not. Thus, we cannot access it easily from within XML resources (you'll get a No resource found that matches the given name: attr 'android:searchViewTextField' error).
Setting SearchView text field background from code
So, the only way to properly substitute background of SearchView text field is to get into it's internals, acquire access to view that has background set based on searchViewTextField and set our own.
NOTE: Solution below depends only on id (android:id/search_plate) of element within SearchView, so it's more SDK-version independent than children traversal (e.g. using searchView.getChildAt(0) to get to the right view within SearchView), but it's not bullet-proof. Especially if some manufacturer decides to reimplement internals of SearchView and element with above-mentioned id is not present - the code won't work.
In SDK, the background for text field in SearchView is declared through nine-patches, so we'll do it the same way. You can find original png images in drawable-mdpi directory of Android git repository. We're interested in two image. One for state when text field is selected (named textfield_search_selected_holo_light.9.png) and one for where it's not (named textfield_search_default_holo_light.9.png).
Unfortunately, you'll have to create local copies of both images, even if you want to customize only focused state. This is because textfield_search_default_holo_light is not present in R.drawable. Thus it's not easily accessible through #android:drawable/textfield_search_default_holo_light, which could be used in selector shown below, instead of referencing local drawable.
NOTE: I was using Holo Light theme as base, but you can do the same with Holo Dark. It seems that there's no real difference in selected state 9-patches between Light and Dark themes. However, there's a difference in 9-patches for default state (see Light vs Dark). So, probably there's no need to make local copies of 9-patches for selected state, for both Dark and Light themes (assuming that you want to handle both, and make them both look the same as in Holo Theme). Simply make one local copy and use it in selector drawable for both themes.
Now, you'll need to edit downloaded nine-patches to your need (i.e. changing blue color to red one). You can take a look at file using draw 9-patch tool to check if it is correctly defined after your edit.
I've edited files using GIMP with one-pixel pencil tool (pretty easy) but you'll probably use the tool of your own. Here's my customized 9-patch for focused state:
NOTE: For simplicity, I've used only images for mdpi density. You'll have to create 9-patches for multiple screen densities if, you want the best result on any device. Images for Holo SearchView can be found in mdpi, hdpi and xhdpi drawable.
Now, we'll need to create drawable selector, so that proper image is displayed based on view state. Create file res/drawable/texfield_searchview_holo_light.xml with following content:
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:state_focused="true"
android:drawable="#drawable/textfield_search_selected_holo_light" />
<item android:drawable="#drawable/textfield_search_default_holo_light" />
</selector>
We'll use the above created drawable to set background for LinearLayout view that holds text field within SearchView - its id is android:id/search_plate. So here's how to do this quickly in code, when creating options menu:
public class MainActivity extends Activity {
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.activity_main, menu);
// Getting SearchView from XML layout by id defined there - my_search_view in this case
SearchView searchView = (SearchView) menu.findItem(R.id.my_search_view).getActionView();
// Getting id for 'search_plate' - the id is part of generate R file,
// so we have to get id on runtime.
int searchPlateId = searchView.getContext().getResources().getIdentifier("android:id/search_plate", null, null);
// Getting the 'search_plate' LinearLayout.
View searchPlate = searchView.findViewById(searchPlateId);
// Setting background of 'search_plate' to earlier defined drawable.
searchPlate.setBackgroundResource(R.drawable.textfield_searchview_holo_light);
return super.onCreateOptionsMenu(menu);
}
}
Final effect
Here's the screenshot of the final result:
How I got to this
I think it's worth metioning how I got to this, so that this approach can be used when customizing other views.
Checking out view layout
I've checked how SearchView layout looks like. In SearchView contructor one can find a line that inflates layout:
inflater.inflate(R.layout.search_view, this, true);
Now we know that SearchView layout is in file named res/layout/search_view.xml. Looking into search_view.xml we can find an inner LinearLayout element (with id search_plate) that has android.widget.SearchView$SearchAutoComplete inside it (looks like ours search view text field):
<LinearLayout
android:id="#+id/search_plate"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="1"
android:layout_gravity="center_vertical"
android:orientation="horizontal"
android:background="?android:attr/searchViewTextField">
Now, we now that the background is set based on current theme's searchViewTextField attribute.
Investigating attribute (is it easily settable?)
To check how searchViewTextField attribute is set, we investigate res/values/themes.xml. There's a group of attributes related to SearchView in default Theme:
<style name="Theme">
<!-- (...other attributes present here...) -->
<!-- SearchView attributes -->
<item name="searchDropdownBackground">#android:drawable/spinner_dropdown_background</item>
<item name="searchViewTextField">#drawable/textfield_searchview_holo_dark</item>
<item name="searchViewTextFieldRight">#drawable/textfield_searchview_right_holo_dark</item>
<item name="searchViewCloseIcon">#android:drawable/ic_clear</item>
<item name="searchViewSearchIcon">#android:drawable/ic_search</item>
<item name="searchViewGoIcon">#android:drawable/ic_go</item>
<item name="searchViewVoiceIcon">#android:drawable/ic_voice_search</item>
<item name="searchViewEditQuery">#android:drawable/ic_commit_search_api_holo_dark</item>
<item name="searchViewEditQueryBackground">?attr/selectableItemBackground</item>
We see that for default theme the value is #drawable/textfield_searchview_holo_dark. For Theme.Light value is also set in that file.
Now, it would be great if this attribute was accessible through R.styleable, but, unfortunately it's not. For comparison, see other theme attributes which are present both in themes.xml and R.attr like textAppearance or selectableItemBackground. If searchViewTextField was present in R.attr (and R.stylable) we could simply use our drawable selector when defining theme for our whole application in XML. For example:
<resources xmlns:android="http://schemas.android.com/apk/res/android">
<style name="AppTheme" parent="android:Theme.Light">
<item name="android:searchViewTextField">#drawable/textfield_searchview_holo_light</item>
</style>
</resources>
What should be modified?
Now we know, that we'll have to access search_plate through code. However, we still don't know how it should look like. In short, we search for drawables used as values in default themes: textfield_searchview_holo_dark.xml and textfield_searchview_holo_light.xml. Looking at content we see that the drawable is selector which reference two other drawables (which occur to be 9-patches later on) based on view state. You can find aggregated 9-patch drawables from (almost) all version of Android on androiddrawables.com
Customizing
We recognize the blue line in one of the 9-patches, so we create local copy of it and change colors as desired.
The above solutions may not work if you are using appcompat library. You may have to modify the code to make it work for appcompat library.
Here is the working solution for appcompat library.
#Override
public boolean onCreateOptionsMenu(Menu menu)
{
getMenuInflater().inflate(R.menu.main_menu, menu);
SearchManager searchManager = (SearchManager) getSystemService(Context.SEARCH_SERVICE);
MenuItem searchMenuItem = menu.findItem(R.id.action_search);
SearchView searchView = (SearchView) MenuItemCompat.getActionView(searchMenuItem);
searchView.setSearchableInfo(searchManager.getSearchableInfo(getComponentName()));
SearchView.SearchAutoComplete searchAutoComplete = (SearchView.SearchAutoComplete)searchView.findViewById(android.support.v7.appcompat.R.id.search_src_text);
searchAutoComplete.setHintTextColor(Color.WHITE);
searchAutoComplete.setTextColor(Color.WHITE);
View searchplate = (View)searchView.findViewById(android.support.v7.appcompat.R.id.search_plate);
searchplate.setBackgroundResource(R.drawable.texfield_searchview_holo_light);
ImageView searchCloseIcon = (ImageView)searchView.findViewById(android.support.v7.appcompat.R.id.search_close_btn);
searchCloseIcon.setImageResource(R.drawable.abc_ic_clear_normal);
ImageView voiceIcon = (ImageView)searchView.findViewById(android.support.v7.appcompat.R.id.search_voice_btn);
voiceIcon.setImageResource(R.drawable.abc_ic_voice_search);
ImageView searchIcon = (ImageView)searchView.findViewById(android.support.v7.appcompat.R.id.search_mag_icon);
searchIcon.setImageResource(R.drawable.abc_ic_search);
return super.onCreateOptionsMenu(menu);
}
Your onCreateOptionsMenu method must be:
#Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.option, menu);
SearchView searchView = (SearchView) menu.findItem(R.id.menu_search).getActionView();
int linlayId = getResources().getIdentifier("android:id/search_plate", null, null);
ViewGroup v = (ViewGroup) searchView.findViewById(linlayId);
v.setBackgroundResource(R.drawable.searchviewredversion);
return super.onCreateOptionsMenu(menu);
}
where your search item is menu_search off course
and here is the searchviewredversion (this one is the xhdpi version): http://img836.imageshack.us/img836/5964/searchviewredversion.png
The solution above doesn't work with ActionBarSherlock 4.2 and therefore it's not backward compatible to Android 2.x. Here is working code which setups SearchView background and hint text on ActionBarSherlock 4.2:
public static void styleSearchView(SearchView searchView, Context context) {
View searchPlate = searchView.findViewById(R.id.abs__search_plate);
searchPlate.setBackgroundResource(R.drawable.your_custom_drawable);
AutoCompleteTextView searchText = (AutoCompleteTextView) searchView.findViewById(R.id.abs__search_src_text);
searchText.setHintTextColor(context.getResources().getColor(R.color.your_custom_color));
}
I've tired to do this as well and I'm using v7.
The application was crashed when I tried to grab the searchPlate via the getIdentifier() so I done it this way:
View searchPlate = searchView.findViewById(android.support.v7.appcompat.R.id.search_plate);
Update
If you are using AndroidX then you can do it like this
View searchPlate = svSearch. findViewById(androidx.appcompat.R.id.search_plate);
if (searchPlate != null) {
AutoCompleteTextView searchText = searchPlate.findViewById(androidx.appcompat.R.id.search_src_text);
if (searchText != null){
searchText.setTextSize(TypedValue.COMPLEX_UNIT_PX, getResources().getDimension(R.dimen.edittext_text_size));
searchText.setMaxLines(1);
searchText.setSingleLine(true);
searchText.setTextColor(getResources().getColor(R.color.etTextColor));
searchText.setHintTextColor(getResources().getColor(R.color.etHintColor));
searchText.setBackground(null);
}
}
I also faced same problem.I used appcompat v7 library and defined custom style for it.
In drawable folder put bottom_border.xml file which looks like this:
<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android" >
<item>
<shape >
<solid android:color="#color/blue_color" />
</shape>
</item>
<item android:bottom="0.8dp"
android:left="0.8dp"
android:right="0.8dp">
<shape >
<solid android:color="#color/background_color" />
</shape>
</item>
<!-- draw another block to cut-off the left and right bars -->
<item android:bottom="2.0dp">
<shape >
<solid android:color="#color/main_accent" />
</shape>
</item>
</layer-list>
In values folder styles_myactionbartheme.xml:
<?xml version="1.0" encoding="utf-8"?>
<resources>
<style name="AppnewTheme" parent="Theme.AppCompat.Light">
<item name="android:windowBackground">#color/background</item>
<item name="android:actionBarStyle">#style/ActionBar</item>
<item name="android:actionBarWidgetTheme">#style/ActionBarWidget</item>
</style>
<!-- Actionbar Theme -->
<style name="ActionBar" parent="Widget.AppCompat.Light.ActionBar.Solid.Inverse">
<item name="android:background">#color/main_accent</item>
<!-- <item name="android:icon">#drawable/abc_ic_ab_back_holo_light</item> -->
</style>
<style name="ActionBarWidget" parent="Theme.AppCompat.Light">
<!-- SearchView customization-->
<!-- Changing the small search icon when the view is expanded -->
<!-- <item name="searchViewSearchIcon">#drawable/ic_action_search</item> -->
<!-- Changing the cross icon to erase typed text -->
<!-- <item name="searchViewCloseIcon">#drawable/ic_action_remove</item> -->
<!-- Styling the background of the text field, i.e. blue bracket -->
<item name="searchViewTextField">#drawable/bottom_border</item>
<!-- Styling the text view that displays the typed text query -->
<item name="searchViewAutoCompleteTextView">#style/AutoCompleteTextView</item>
</style>
<style name="AutoCompleteTextView" parent="Widget.AppCompat.Light.AutoCompleteTextView">
<item name="android:textColor">#color/text_color</item>
<!-- <item name="android:textCursorDrawable">#null</item> -->
<!-- <item name="android:textColorHighlight">#color/search_view_selected_text</item> -->
</style>
</resources>
I defined custommenu.xml file for displaying menu:
<menu xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:com.example.actionbartheme="http://schemas.android.com/apk/res-auto" >
<item android:id="#+id/search"
android:title="#string/search_title"
android:icon="#drawable/search_buttonn"
com.example.actionbartheme:showAsAction="ifRoom|collapseActionView"
com.example.actionbartheme:actionViewClass="android.support.v7.widget.SearchView"/>
Your activity should extend ActionBarActivity instead of Activity.
#Override
public boolean onCreateOptionsMenu(Menu menu)
{
// Inflate the menu; this adds items to the action bar if it is present.
MenuInflater inflater = getMenuInflater();
inflater.inflate(R.menu.custommenu, menu);
}
In manifest file:
<application
android:allowBackup="true"
android:icon="#drawable/ic_launcher"
android:label="#string/app_name"
android:theme="#style/AppnewTheme" >
For more information see here:
Here http://www.jayway.com/2014/06/02/android-theming-the-actionbar/
First, let's create an XML file called search_widget_background.xml, to be used as a drawable, i.e. under drawable directory.
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle" >
<solid android:color="#color/red" />
</shape>
This drawable will be used as the background for our search widget. I set the color to red because that's what you asked for, but you can set it to any color defined by #color tag. You can even modify it further using the attributes defined for shape tag (make rounded corners, do an oval background, etc.).
Next step is to set the background of our search widget to this one. This can be accomplished by the following:
public boolean onCreateOptionsMenu(Menu menu) {
SearchView searchView = (SearchView)menu.findItem(R.id.my_search_view).getActionView();
Drawable d = getResources().getDrawable(R.drawable.search_widget_background);
searchView.setBackground(d);
...
}
public boolean onCreateOptionsMenu(Menu menu) {
........
// Set the search plate color
int linlayId = getResources().getIdentifier("android:id/search_plate", null, null);
View view = searchView.findViewById(linlayId);
Drawable drawColor = getResources().getDrawable(R.drawable.searchcolor);
view.setBackground( drawColor );
........
}
and this is the searchablecolor.xml file
<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android" >
<item>
<shape >
<solid android:color="#ffffff" />
</shape>
</item>
<!-- main color -->
<item android:bottom="1.5dp"
android:left="1.5dp"
android:right="1.5dp">
<shape >
<solid android:color="#2c4d8e" />
</shape>
</item>
<!-- draw another block to cut-off the left and right bars -->
<item android:bottom="18.0dp">
<shape >
<solid android:color="#2c4d8e" />
</shape>
</item>
</layer-list>
I was digging about that a lot and finally I found this solution and it works for me!
You can use this
If you use appcompat try this:
ImageView searchIconView = (ImageView) searchView.findViewById(android.support.v7.appcompat.R.id.search_button);
searchIconView.setImageResource(R.drawable.yourIcon);
If you use androidx try this:
ImageView searchIconView = (ImageView) searchView.findViewById(androidx.appcompat.R.id.search_button);
searchIconView.setImageResource(R.drawable.yourIcon);
It will change the default serchview icon.
Hope it helps!
I explained in the end of this post with images
this is apply for xamarin forms. But i think you can understand it, because it is based on the source code of searchview of android
How to change searchbar cancel button image in xamarin forms
If you are inflating Searchview like this "getMenuInflater().inflate(R.menu.search_menu, menu);". Then you can customize this searchview via style.xml like below.
<style name="AppTheme" parent="Theme.AppCompat.DayNight.NoActionBar">
<item name="searchViewStyle">#style/SearchView.ActionBar</item>
</style>
<style name="SearchView.ActionBar" parent="Widget.AppCompat.SearchView.ActionBar">
<item name="queryBackground">#drawable/drw_search_view_bg</item>
<item name="searchHintIcon">#null</item>
<item name="submitBackground">#null</item>
<item name="closeIcon">#drawable/vd_cancel</item>
<item name="searchIcon">#drawable/vd_search</item>
</style>

Is it possible to grey out (not just disable) a MenuItem in Android?

There's a question for the same functionality on Blackberry, and a few different threads referred to this bug (which has since been closed without resolution as far as I can tell), but I haven't found one specifically for Android.
I'm calling setEnabled(false) on certain MenuItems based on some state, but they visually look the same. I'd like them to be offset in some way, so that the user knows that the option currently isn't available -- is there any way to do that?
On all android versions, easiest way to use this to SHOW a menu action icon as disabled AND make it FUNCTION as disabled as well:
#Override
public boolean onPrepareOptionsMenu(Menu menu) {
MenuItem item = menu.findItem(R.id.menu_my_item);
if (myItemShouldBeEnabled) {
item.setEnabled(true);
item.getIcon().setAlpha(255);
} else {
// disabled
item.setEnabled(false);
item.getIcon().setAlpha(130);
}
}
I had the same issue. There are two ways of getting this to work:
Put your icons in a StateList so that a different icon will be used on disable
What I use now. Change the icon yourself with something like this in onPrepareOptionsMenu():
public boolean onPrepareOptionsMenu(Menu menu) {
boolean menusEnabled = reachedEndOfSlidehow(); // enable or disable?
MenuItem item = menu.findItem(R.id.menu_next_slide);
Drawable resIcon = getResources().getDrawable(R.drawable.ic_next_slide);
if (!menusEnabled)
resIcon.mutate().setColorFilter(Color.GRAY, PorterDuff.Mode.SRC_IN);
item.setEnabled(menusEnabled); // any text will be automatically disabled
item.setIcon(resIcon);
}
You can call invalidateOptionsMenu() (or from ABS, supportInvalidateOptionsMenu()) to rebuild the menu.
EDIT: Updated solution 2
Source: https://groups.google.com/forum/?fromgroups#!topic/actionbarsherlock/Z8Ic8djq-3o
I found a new way to solve this issue using a drawable selector xml file. You just create a selector with the icon you want to use in your menu item, then you can either change the tint, alpha or both of the bitmap:
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:state_enabled="true">
<bitmap android:src="#drawable/ic_menu_item"
android:tint="#color/enabled_color"
android:alpha="#integer/enabled_alpha"/>
</item>
<item android:state_enabled="false">
<bitmap android:src="#drawable/ic_menu_item"
android:tint="#color/disabled_color"
android:alpha="#integer/disabled_alpha"/>
</item>
</selector>
As a side note; I like to set the tint to "?android:attr/textColorPrimary" for enabled state and "?android:attr/textColorHint" for disabled state. This way it will adjust depending on the theme used.
Then you can just set the icon in your menu xml file to the selector resource:
<menu xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto">
<item android:id="#+id/menu_action"
android:orderInCategory="0"
android:title="#string/title_menu_action"
android:icon="#drawable/ic_menu_item_selector"
app:showAsAction="ifRoom"/>
</menu>
Then when you call item.setEnabled(enabled) the color and/or alpha of the icon will change along with the state!
The way I did it is by using "itemIconTint" in NavigationView, you can also grey out the text by using "itemTextColor"
This is Navigationview:
<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:itemBackground="#color/white"
android:background="#color/white"
app:itemTextColor="#color/menu_text_color"
app:itemIconTint="#color/menu_text_color"
app:menu="#menu/main_drawer" />
and the "#color/menu_text_color" is a selector:
<?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/primaryColor" />
<item android:state_enabled="false" android:color="#color/disabled_text_color" />
<item android:color="#color/primaryText" />
</selector>
Finally, if you want to disable a menuitem,
MenuItem item = mNavigationView.getMenu().findItem(R.id.your_menu_item);
item.setEnabled(isEnable);
Done!
I was having difficulty with this on modern android with MaterialComponents theme. My problem was I had set <item name="actionMenuTextColor">#color/blue</item> in styles.xml and this overrides the text color whether the item is enabled or disabled. The solution is to set a Color state list and not a color directly.
My styles attribute now looks like:
<item name="actionMenuTextColor">#color/menu_color_selector</item>
I had an issue where neither my the text nor the icon was visibly changing. The other answers either didn't work for me or weren't very elegant. Here's an answer that works for the latest Material recommendations.
You should be able to simply call menu.findItem(R.id.menu_my_item).isEnabled = false in onPrepareOptionsMenu(menu: Menu).
(If you need onPrepareOptionsMenu to run again, you can simply call invalidateOptionsMenu() or activity?.invalidateOptionsMenu() (from a fragment) and the application will queue up the menu to be recreated. Alternatively you can store off the menu item in a member variable to modify it later, but be careful to destroy your reference to it within onDestroyOptionsMenu to avoid a memory leak.)
The fact that the menu item is disabled should be enough to grey out the text or the icon automatically. The difficulty is in setting up your styles to make this work.
Short Answer
First create a color state list my_color_state_list.xml that you want your icons and text to use (e.g. black when enabled, grey when disabled). (See the full answer for an example.)
If you're using com.google.android.material.appbar.MaterialToolbar, you can tell it to use this selector for icons and text by providing a custom theme overlay. In your activity's XML, give the toolbar the attribute android:theme="#style/Foo" and define that style somewhere as:
<style name="Foo">
<item name="colorControlNormal">#color/my_color_state_list</item>
<item name="actionMenuTextColor">#color/my_color_state_list</item>
</style>
Now when the menu item is enabled or disabled via menu.findItem(R.id.menu_my_item).isEnabled = false the text will automatically change color, and any icons which use the color ?attr/colorControlNormal will also automatically change color.
Full answer
My starting place
My menu items are part of a Material toolbar. This answer may help for other kinds of toolbar/app bar, but your mileage may vary. In my activity I have something like this:
<com.google.android.material.appbar.MaterialToolbar
android:id="#+id/toolbar"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
android:theme="#style/ThemeOverlay.MaterialComponents.Toolbar.Surface"/>
and the theme I'm using looks something like this:
<style name="Theme.MyApp" parent="Theme.MaterialComponents.DayNight.NoActionBar">
<item name="colorPrimary">#color/blue</item>
<item name="colorSecondary">#color/green</item>
<item name="colorSurface">#color/lightGrey</item>
<item name="colorOnSurface">#color/black</item>
[...]
<item name="windowActionModeOverlay">true</item>
</style>
It is also convention that the icon you use in buttons and menu items (and everywhere really) should have their default color be ?attr/colorControlNormal. So for example I might have a vector image which looks like:
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportWidth="24"
android:viewportHeight="24"
android:tint="?attr/colorControlNormal"
android:tintMode="src_atop">
<path android:pathData="..." android:fillColor="#android:color/white"/>
</vector>
If you download an icon from Material Icons you will see they all use colorControlNormal.
What I needed to do
If you look back at the definition of my toolbar, you will see it uses a ThemeOverlay ThemeOverlay.MaterialComponents.Toolbar.Surface which is defined as:
<style name="ThemeOverlay.MaterialComponents.Toolbar.Surface" parent="">
<item name="colorControlNormal">#color/material_on_surface_emphasis_medium</item>
<item name="actionMenuTextColor">#color/material_on_surface_emphasis_medium</item>
</style>
This sets the menu item text color and icon color to #color/material_on_surface_emphasis_medium which does not respond to being enabled or not. #color/material_on_surface_emphasis_medium looks like:
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:alpha="#dimen/material_emphasis_medium" android:color="?attr/colorOnSurface"/>
</selector>
(You may be using ThemeOverlay.MaterialComponents.Toolbar.Primary instead, which has a similar issue - it simply uses colorOnPrimary.)
We need to replace this with our own color state list which responds to enabled state. So, make a new file res/color/menu_item_selector.xml that looks something like this:
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:state_enabled="true" android:alpha="#dimen/material_emphasis_medium" android:color="?attr/colorOnSurface"/>
<item android:alpha="#dimen/material_emphasis_disabled" android:color="?attr/colorOnSurface"/>
</selector>
You see I've used the same conventions that the material library does by using their constants to define the alpha values, and I used colorOnSurface as my color. If you were using ThemeOverlay.MaterialComponents.Toolbar.Primary you would want colorOnPrimary instead. Of course you can use any color or alpha here, it's up to you.
And now make a new ThemeOverlay in res/values/styles.xml to point to this selector, inheriting from whatever ThemeOverlay you were using:
<!-- Toolbar - overrides the menu text color to use a selector that responds to whether it's enabled or not -->
<style name="ThemeOverlay.MyTheme.Toolbar" parent="ThemeOverlay.MaterialComponents.Toolbar.Surface">
<!-- Color used in the icons of menu actions (i.e. non-overflow menu items). This is just convention, this will affect anything that uses ?attr/colorControlNormal) -->
<item name="colorControlNormal">#color/menu_item_color_selector</item>
<!-- Color used in the text of menu actions (i.e. non-overflow menu items) -->
<item name="actionMenuTextColor">#color/menu_item_color_selector</item>
</style>
And now finally we can apply this ThemeOverlay to the toolbar:
<com.google.android.material.appbar.MaterialToolbar
android:id="#+id/toolbar"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
android:theme="#style/ThemeOverlay.MyTheme.Toolbar"/>
setEnabled(false) works fine on API Level < 14 but on 14 the item still clickable.
Have a look at this link
setEnabled can also be used for MenuItems.
Here's a simple way to do it (using Kotlin):
fun changeMenuItemColour(enabled: Boolean) {
var menuItem = SpannableString(mCustomToolbar?.menu?.findItem(R.id.some_menu_item)?.title)
var style = activity?.resources?.getColor(R.color.darkGraphite)!!
if (enabled) style = activity?.resources?.getColor(R.color.black)!!
menuItem.setSpan(ForegroundColorSpan(style), 0, menuItem.length, 0)
}

Custom Notification View

I would like to create a notification icon view that looks similar to the Google+ app's notification. The difference will be that I need to be able to change the color at runtime where as the Google+ icons gray or red so I'm assuming they are using a StateListDrawable.
What is the best approach for this? I'd prefer to have the rounded clipped corners and have the option to have a drawable inside. This custom view will be placed in the Action Bar as well. I still need the view to respond to android:background state list drawables so I can have the click and selected accordance working.
This custom view will be placed in the action bar as well.
I solved this by doing the following.
Created this to make the rounded corner shape with a solid color. This also adds a translucent black to give it a pressed look against a blackground.
res/drawable/shape_notification.xml
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle">
<stroke android:color="#33000000" android:width="2dp"/>
<corners android:radius="4dp" />
<solid android:color="#99333333"/>
</shape>
The layer drawable will be used as the actual drawable on the action bar item. It has the background (written above) overlayed with the wrench icon.
res/drawable/layer_customizer.xml
<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android" >
<item android:drawable="#drawable/shape_notification" />
<item android:drawable="#drawable/ic_menu_preferences" />
</layer-list>
Java code to change the color. The target view is the object that is assigned the layer_customizer drawable. The color passed in will change the shape_notification.xml's solid tag color.
public static void setCustomizerDrawableColor(final View target, final int color) {
final Drawable d = target.getDrawable();
LayerDrawable layer = (LayerDrawable)d;
GradientDrawable gradient = (GradientDrawable)layer.getDrawable(0);
gradient.setColor(color);
gradient.invalidateSelf();
layer.invalidateSelf();
target.invalidate();
}
Create a layout using these layers.
res/layout/actionview_customizer.xml
<?xml version="1.0" encoding="utf-8"?>
<ImageButton xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="#+id/ActionViewCustomizer"
android:src="#drawable/layer_customizer"
android:contentDescription="#string/customize"
style="#style/ActionBarButton" />
To get the custom layout to put into the ActionBar add this menu item into it:
res/menu/actionbar_main.xml
<item android:id="#+id/MenuItemCustomize"
android:icon="#drawable/layer_customizer"
android:title="#string/customize"
android:showAsAction="always"
android:actionLayout="#layout/actionview_customizer"
/>
Then after loading the Action Bar use this code to get the handle to the button. This happens in your Activity.
#Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.actionbar_main, menu);
final ActionBar actionBar = getActionBar();
final MenuItem customizerItem = menu.findItem(R.id.MenuItemCustomize);
View v = customizerItem.getActionView();
customizerActionView = (ImageButton) v;
customizerActionView.setOnClickListener(new OnClickListener() {
public void onClick(View v) {
onOptionsItemSelected(customizerItem);
}
});
}
If you want to see the full source working together look at the app source code I use this in. http://code.google.com/p/motivatormaker-android/source/browse/MakeMotivator/src/com/futonredemption/makemotivator/activities/MainActivity.java

Categories

Resources