MenuItem tinting on AppCompat Toolbar
Because if you take a look at the source code of the TintManager in AppCompat, you will see:
/**
* Drawables which should be tinted with the value of {@code R.attr.colorControlNormal},
* using the default mode.
*/
private static final int[] TINT_COLOR_CONTROL_NORMAL = {
R.drawable.abc_ic_ab_back_mtrl_am_alpha,
R.drawable.abc_ic_go_search_api_mtrl_alpha,
R.drawable.abc_ic_search_api_mtrl_alpha,
R.drawable.abc_ic_commit_search_api_mtrl_alpha,
R.drawable.abc_ic_clear_mtrl_alpha,
R.drawable.abc_ic_menu_share_mtrl_alpha,
R.drawable.abc_ic_menu_copy_mtrl_am_alpha,
R.drawable.abc_ic_menu_cut_mtrl_alpha,
R.drawable.abc_ic_menu_selectall_mtrl_alpha,
R.drawable.abc_ic_menu_paste_mtrl_am_alpha,
R.drawable.abc_ic_menu_moreoverflow_mtrl_alpha,
R.drawable.abc_ic_voice_search_api_mtrl_alpha,
R.drawable.abc_textfield_search_default_mtrl_alpha,
R.drawable.abc_textfield_default_mtrl_alpha
};
/**
* Drawables which should be tinted with the value of {@code R.attr.colorControlActivated},
* using the default mode.
*/
private static final int[] TINT_COLOR_CONTROL_ACTIVATED = {
R.drawable.abc_textfield_activated_mtrl_alpha,
R.drawable.abc_textfield_search_activated_mtrl_alpha,
R.drawable.abc_cab_background_top_mtrl_alpha
};
/**
* Drawables which should be tinted with the value of {@code android.R.attr.colorBackground},
* using the {@link android.graphics.PorterDuff.Mode#MULTIPLY} mode.
*/
private static final int[] TINT_COLOR_BACKGROUND_MULTIPLY = {
R.drawable.abc_popup_background_mtrl_mult,
R.drawable.abc_cab_background_internal_bg,
R.drawable.abc_menu_hardkey_panel_mtrl_mult
};
/**
* Drawables which should be tinted using a state list containing values of
* {@code R.attr.colorControlNormal} and {@code R.attr.colorControlActivated}
*/
private static final int[] TINT_COLOR_CONTROL_STATE_LIST = {
R.drawable.abc_edit_text_material,
R.drawable.abc_tab_indicator_material,
R.drawable.abc_textfield_search_material,
R.drawable.abc_spinner_mtrl_am_alpha,
R.drawable.abc_btn_check_material,
R.drawable.abc_btn_radio_material
};
/**
* Drawables which contain other drawables which should be tinted. The child drawable IDs
* should be defined in one of the arrays above.
*/
private static final int[] CONTAINERS_WITH_TINT_CHILDREN = {
R.drawable.abc_cab_background_top_material
};
Which pretty much means they have particular resourceIds whitelisted to be tinted.
But I guess you can always see how they're tinting those images and do the same. It's as easy as set the ColorFilter on a drawable.
Why some menu item in the toolbar appears in a different colour?
I can't explain why the search icon is not white when you run the app, but the help icon clearly is marked to be tinted blue (android:tint="#145979"
). android:tint
in the parent vector
element overrides the color of any child path
elements.
I suggest you set android:tint="?android:attr/colorForeground"
in the top level vector
element of all of these so they can follow your theming. Then if you decide to make them a different color or have a day/night theme where they are a different color during the day, you only have to change it in the theme in one spot, and they will always match the overflow icon color.
If you want white text and icons on your action bar, I suggest you use a parent theme that has DarkActionBar
in its name, or if you are using NoActionBar
and including a Toolbar in your layout that you set as the support action bar, then set an actionBarTheme
with a DarkActionBar parent, such as including:
<item name="actionBarTheme">@style/ThemeOverlay.MaterialComponents.Dark.ActionBar</item>
This will make the overflow icon white as well.
Edit: I realized the above only works if you use a theme with a window decor action bar instead of a NoActionBar theme with a Toolbar in the layout.
The help icon needed its tint changed to white in the XML.
From the comments: The search button was getting externally tinted because of it having actionViewClass
in the menu XML. It was using colorOnPrimary
from the theme to tint its icon. So instead of just using @style/ThemeOverlay.MaterialComponents.Dark.ActionBar
as the actionBarTheme
, you had to create a custom action bar overlay theme and use that.
<style name="MyThemeOverlay_Toolbar" parent="ThemeOverlay.MaterialComponents.Toolbar.Primary">
<item name="colorOnPrimary">@color/colorWhite</item>
</style>
<!-- and inside the app theme: -->
<item name="actionBarTheme">@style/MyThemeOverlay_Toolbar</item>
Toolbar icon tinting on Android
I see this question is getting some views so I'm going to post an answer for those who don't read the comments.
My conjectures in the question were all wrong and it is not a matter of alpha channels, at least not externally. The fact is simply that, quoting @alanv ,
AppCompat only tints its own icons. For now, you will need to manually
tint any icons that you're providing separately from AppCompat.
This might change in the future but also might not. From this answer you can also see the list of icons (they all belong to the internal resource folder of appcompat, so you can't change them) that are automatically tinted and with which color.
Personally I use a colorControlNormal
which is black or white (or similar shades), and import the icons with that particular color. Colored icons on a colored background look a little bad. However, another solution I found pleasant is this class on github. You just call MenuColorizer.colorMenu()
when you create the menu.
Tint menu icons
There may be a better way to do this, but one option is to redraw the icon in code.
Suppose you have a menu item for favorites and want to tint it gray:
MenuItem favoriteItem = menu.findItem(R.id.action_favorite);
Drawable newIcon = (Drawable)favoriteItem.getIcon();
newIcon.mutate().setColorFilter(Color.argb(255, 200, 200, 200), PorterDuff.Mode.SRC_IN);
favoriteItem.setIcon(newIcon);
You can also use a color resource like
newIcon.mutate().setColorFilter(getResources().getColor(R.color.myCustomTint), PorterDuff.Mode.SRC_IN);
MenuItem tint for all apis - iconTint for apis 26 -
Okay, I've already found a solution.
By handling it with DrawableCompat :
menu?.getItem(0)?.icon?.let {
DrawableCompat.setTint(
it,
ContextCompat.getColor(this, R.color.black)
)
}
Tint Navigation Icon in Toolbar
The appcompat navigation button - which is simply an AppCompatImageButton
- can be styled through the toolbarNavigationButtonStyle
attribute. The default style for that in the AppCompat
themes is Widget.AppCompat.Toolbar.Button.Navigation
, and we can extend that style to add a tint
attribute value. For example:
<style name="AppTheme" parent="Theme.AppCompat.Light.NoActionBar">
...
<item name="toolbarNavigationButtonStyle">@style/Toolbar.Button.Navigation.Tinted</item>
</style>
<style name="Toolbar.Button.Navigation.Tinted" parent="Widget.AppCompat.Toolbar.Button.Navigation">
<item name="tint">@color/nav_button_tint</item>
</style>
There are a couple of caveats to be aware of when using this method.
Prior to support library version 25.4.0, AppCompatImageButton
did not offer its own tint
attribute, and therefore a tint
attribute in the app's namespace will not apply (and just won't exist, unless defined elsewhere). It is necessary to use the platform android:tint
attribute if using support library version 25.3.0 or earlier.
Unfortunately, this leads to another catch, in that the platform tint prior to Lollipop (API level 21) can handle only simple, single color values, and using a ColorStateList
(<selector>
) resource value will cause an Exception
to be thrown. This poses no problems if the android:tint
value is a simple color, but it is often desired to tint the navigation icon to match another theme color attribute, which may very well be a ColorStateList
. In this case, it would be necessary to create separate styles in res/values/
and res/values-21/
, specifying a simple color value for android:tint
in res/values/
.
For example, if tinting to match the theme's primary text color:
res/values/styles.xml
<item name="android:tint">@color/normal_text_color</item>
res/values-v21/styles.xml
<item name="android:tint">?android:textColorPrimary</item>
You need only concern yourself with the notes above if you're stuck using a support library version less than 25.4.0.
Action bar menu item not tinting colour properly
Might have to do with the DrawableCompat. I always do tinting using the ColorFilter with PorterDuff, as it allows to specify exactly what type of recolouring you want (SRC_IN mostly fits the result I want to achieve)
Try to change it like this:
Drawable drawable = menu.findItem(R.id.action_info).getIcon();
drawable.setColorFilter(Color.GREEN, PorterDuff.Mode.SRC_IN);
menu.findItem(R.id.action_info).setIcon(drawable); // Actualy, we don't need to do this
EDIT:
I see. This effect is caused by the image you are using. I guess you use the default icon ic_menu_info_details
which has opacity built in. It is better to use your own icon in order to color it as needed.
Basically we can take the same icon, without opacity. And then this PorterDuff method works as expected (and probably your earlier code too).
You can easily find the icon and add it to your project.
Option 1:
Finding the icon here: http://romannurik.github.io/AndroidAssetStudio/icons-actionbar.html
And add it to your drawables folder
Option 2:
Using vector drawables, then the images will be scaled automatically on each device too.
Right click on the drawable folder
Go to
New
->Vector Asset
Click the change icon button, and find the Info icon
Dont forget to change your menu.xml
so that you use the new icon
Related Topics
Differencebetween System Apps and Privileged Apps on Android
Unzip a Zipped File on Sd Card in Android Application
Android Mediarecorder - "Start Failed: -19"
What Is the Correct Way to Specify Dimensions in Dip from Java Code
How to Get Toolbar from Fragment
How to Use the Android Volley API
Android Phone Orientation Overview Including Compass
Manipulating Data on Webs in Android
How to Show Toast in Asynctask in Doinbackground
Can the Android Emulator Record and Play Back Audio Using Pc Hardware
Certpathvalidatorexception:Trust Anchor for Certificate Path Not Found - Retrofit Android
Gridlayout and Row/Column Span Woe
Buttons Not Visible on the Application. What's Wrong
How to Import a Native Library (.So File) into Eclipse
Android:Windowsoftinputmode="Adjustresize" Doesn't Make Any Difference
[Install_Failed_No_Matching_Abis: Failed to Extract Native Libraries, Res=-113]