Change Toolbar overflow icon color
Asked Answered
U

6

29

I have an android.support.v7.widget Toolbar in my Android app. The background color of this is bright orange and the best looking color on top of this would be white instead of black.

I have the default color on black and not white. Since it would conflict with other stuff, that is almost impossible to override. I cannot change the primary text color to white!

I've managed to change the title color. What I'm looking for right now is how I can change the action button color as well (to white).

enter image description here

My code:

Main activity:

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
xmlns:app="http://schemas.android.com/apk/res-auto"
tools:context=".UI.activities.MainActivity">

<android.support.v7.widget.Toolbar
    android:id="@+id/r2_toolbar"
    android:layout_width="match_parent"
    android:layout_height="?attr/actionBarSize"
    android:background="?attr/colorPrimary"
    android:elevation="4dp"
    app:titleTextColor="@color/primary_text_material_light"
    app:subtitleTextColor="@color/primary_text_material_light"
    android:theme="@style/R2Theme.Toolbar"/>

<fragment android:name="com.r2retail.r2retailapp.UI.fragments.SetupFragment"
    android:layout_below="@+id/r2_toolbar"
    android:id="@+id/list"
    android:layout_weight="1"
    android:layout_width="match_parent"
    android:layout_height="match_parent" />


</RelativeLayout>

Menu bar:

<?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/about"
    android:icon="@drawable/ic_menu"
    android:title="About"
    app:showAsAction="never"/>

</menu>

Styles:

<resources>

<style name="R2Theme" parent="Theme.AppCompat.Light.NoActionBar">=
    <item name="colorPrimary">@color/colorPrimary</item>
    <item name="colorPrimaryDark">@color/colorPrimaryDark</item>
    <item name="colorAccent">@color/colorPrimary</item>
    <item name="android:textColorPrimary">@color/secondary_text_material_dark</item>
    <item name="android:textColorSecondaryInverse">@color/primary_text_material_light</item>
</style>

<style name="R2Theme.Toolbar" parent="R2Theme">
    <item name="actionMenuTextColor">@color/primary_text_material_light</item>
</style>

</resources>
Unhealthy answered 21/4, 2017 at 8:43 Comment(3)
Is there is not way to customize the ic_menu color, directly from it's file like changing fillColor ?Korella
Does this answer your question? Change color of the overflow button on ActionBarLiba
Note to reviewers: Toolbar and the action bar are two different widgets.Putrescine
W
90

In styles:

<style name="AppTheme" parent="Theme.AppCompat.Light.DarkActionBar">
    ...
    <item name="actionOverflowButtonStyle">@style/MyOverflowButtonStyle</item>
</style>

<style name="MyOverflowButtonStyle" parent="Widget.AppCompat.ActionButton.Overflow">
    <item name="android:tint">#62ff00</item>
</style>

Result:

enter image description here

Welker answered 21/4, 2017 at 9:33 Comment(6)
@Welker thanks, it worked but what if i want to change the back arrow(in the child activity) color too?Far
@Far welcome. Have you tried this?Welker
@azizbekian, yeah after that only i found that link and yup it worked but failed to update here, thanks a lotFar
Works very well with the new BottomAppBar as well. Have an upvote.Monmouth
Does not work if i use parent="Theme.AppCompat.Light.NoActionBar" and apply the AppTheme to whole application.Homoousian
Not working for me either. I have a NoActionBar theme applied to the activity in the manifest, but the rest is identical to above.Madrigal
O
6

The solution is to replace icon itself.

1st

Go to values/styles and in your styles.xml file add:

<style name="AppTheme" parent="Theme.AppCompat.Light.DarkActionBar">
        <!-- Customize your theme here. -->
        <item name="android:actionOverflowButtonStyle">@style/MyActionButtonOverflow</item>
</style>

<style name="MyActionButtonOverflow" parent="android:style/Widget.Holo.Light.ActionButton.Overflow">
    <!--Here you need to put name of drawable you will create during the next step-->
    <item name="android:src">@drawable/your_white_icon</item> 
</style>

2nd

Then go to drawable folder. Right mouse click -> new -> vector asset. Then press on Icon image and choose from suggested icon named ic_more_vert_black_24dp.

Customize it -> press next -> finish.

Then open newly created icon file. Code looks like this.

<vector xmlns:android="http://schemas.android.com/apk/res/android"
        android:width="24dp"
        android:height="24dp"
        android:viewportWidth="24.0"
        android:viewportHeight="24.0">
    <path
        android:fillColor="#FFFFFFFF" <!-- Here u can change color-->
        android:pathData="M12,8c1.1,0 2,-0.9 2,-2s-0.9,-2 -2,-2 -2,0.9 -2,2 0.9,2 2,2zM12,10c-1.1,0 -2,0.9 -2,2s0.9,2 2,2 2,-0.9 2,-2 -0.9,-2 -2,-2zM12,16c-1.1,0 -2,0.9 -2,2s0.9,2 2,2 2,-0.9 2,-2 -0.9,-2 -2,-2z"/>
</vector>

Change fillColor attribute to the color you need. Put this file to the styles how described in 1st step.

Voila! Color of our three dots changed not depending on base app styles (result for #FF2012 color).

enter image description here

Onus answered 21/4, 2017 at 9:4 Comment(0)
M
5

An alternative way, in code instead of XML:

public static boolean colorizeToolbarOverflowButton(@NonNull Toolbar toolbar, @ColorInt int color) {
    final Drawable overflowIcon = toolbar.getOverflowIcon();
    if (overflowIcon == null)
        return false;
    toolbar.setOverflowIcon(getTintedDrawable(toolbar.getContext(), overflowIcon, toolbarIconsColor));
    return true;
}

public static Drawable getTintedDrawable(@NonNull Context context, @NonNull Drawable inputDrawable, @ColorInt int color) {
    Drawable wrapDrawable = DrawableCompat.wrap(inputDrawable);
    DrawableCompat.setTint(wrapDrawable, color);
    DrawableCompat.setTintMode(wrapDrawable, Mode.SRC_IN);
    return wrapDrawable;
}

The function will return true if succeeded to colorize the overflow icon.

And another alternative, in case you prefer not to use a tinted drawable:

public static boolean colorizeToolbarOverflowButton(@NonNull Toolbar toolbar, @ColorInt Integer color) {
    final Drawable overflowIcon = toolbar.getOverflowIcon();
    if (overflowIcon == null)
        return false;
    final PorterDuffColorFilter colorFilter = toolbarIconsColor == null ? null : new PorterDuffColorFilter(toolbarIconsColor, PorterDuff.Mode.MULTIPLY);
    overflowIcon.setColorFilter(colorFilter);
    return true;
}

In addition, if you wish to colorize the icons of the action items and the nav item, you can try this (based on here):

/**
 * Use this method to colorize toolbar icons to the desired target color
 *
 * @param toolbarView       toolbar view being colored
 * @param toolbarIconsColor the target color of toolbar icons
 */
@JvmStatic
@UiThread
fun colorizeToolbarActionItemsAndNavButton(toolbarView: Toolbar, @ColorInt toolbarIconsColor: Int?) {
    //https://snow.dog/blog/how-to-dynamicaly-change-android-toolbar-icons-color/
    val colorFilter = if (toolbarIconsColor == null) null else PorterDuffColorFilter(toolbarIconsColor, Mode.MULTIPLY)
    for (i in 0 until toolbarView.childCount) {
        val v = toolbarView.getChildAt(i)
        //Step 1 : Changing the color of back button (or open drawer button).
        if (v is ImageButton) {
            //Action Bar back button
            v.drawable.mutate().colorFilter = colorFilter
        }
        if (v is ActionMenuView) {
            for (j in 0 until v.childCount) {
                //Step 2: Changing the color of any ActionMenuViews - icons that
                //are not back button, nor text, nor overflow menu icon.
                val innerView = v.getChildAt(j)
                if (innerView is ActionMenuItemView) {
                    val drawablesCount = innerView.compoundDrawables.size
                    for (k in 0 until drawablesCount) {
                        if (innerView.compoundDrawables[k] != null) {
                            innerView.post { innerView.compoundDrawables[k].mutate().colorFilter = colorFilter }
                        }
                    }
                }
            }
        }
    }
}

Usage:

override fun onCreateOptionsMenu(menu: Menu): Boolean {
    menuInflater.inflate(R.menu.menu_main, menu)
    toolbar.doOnPreDraw {
        colorizeToolbarActionItemsAndNavButton(toolbar,0xffff0000.toInt())
    }
    return true
}
Meta answered 20/7, 2017 at 9:17 Comment(0)
L
2

For AndroidX users (really don't know if it works using old Support Library):

TL;DR:

<style name="MyToolbarTheme">
  <item name="colorControlNormal">@color/white</item>
</style>

Apply MyToolbarTheme to your Toolbar view.


Long explanation:

Widget.AppCompat.ActionButton.Overflow extends Base.Widget.AppCompat.ActionButton.Overflow. We'll be talking about the latter:

On the default implementation:

<style name="Base.Widget.AppCompat.ActionButton.Overflow" parent="RtlUnderlay.Widget.AppCompat.ActionButton.Overflow">
  <item name="srcCompat">@drawable/abc_ic_menu_overflow_material</item>
  ...
</style>

On API 21 implementation:

<style name="Base.Widget.AppCompat.ActionButton.Overflow" parent="android:Widget.Material.ActionButton.Overflow">
  <item name="android:src">@null</item>
  <item name="srcCompat">@drawable/abc_ic_menu_overflow_material</item>
</style>

On API 23 and higher implementation:

It extends android:Widget.Material.ActionButton.Overflow.

<style name="Widget.Material.ActionButton.Overflow">
  <item name="src">@drawable/ic_menu_moreoverflow_material</item>
  ...
</style>

We can notice that every implementation uses @drawable/ic_menu_moreoverflow_material.

Inside this drawable's implementation you can see the following:

android:tint="?attr/colorControlNormal"
Liba answered 15/4, 2020 at 21:36 Comment(0)
L
0

If you want to change the color of icons (Navigation icon, menu item icons) in your toolbar, you can simply use the code below. I had saved problem and solved using this.

<!--Light Theme-->
<style name="AppThemeLight" parent="Theme.MaterialComponents.Light.NoActionBar">
    <!--other colors and properties-->
    <item name="iconTint">@color/colorBlack</item>
</style>

<!-- Dark/Night theme. -->
<style name="AppThemeDark" parent="Theme.MaterialComponents.NoActionBar">
    <!--other colors and properties-->
    <item name="iconTint">@color/colorWhite</item>
</style>
Legere answered 2/10, 2020 at 6:54 Comment(0)
E
0

If anyone's looking to change it programmatically, and the following didn't work:

mBinding.toolbar.overflowIcon?.setTint(Color.WHITE)

OR

mBinding.toolbar.overflowIcon?.setColorFilter(Color.WHITE, PorterDuff.Mode.SRC_ATOP)

OR

mBinding.toolbar.overflowIcon?.colorFilter = BlendModeColorFilterCompat.createBlendModeColorFilterCompat(Color.WHITE, BlendModeCompat.SRC_ATOP)

OR

val overflowIcon = ContextCompat.getDrawable(this, R.drawable.dots_vertical_black)
overflowIcon?.setTint(Color.WHITE)
mBinding.toolbar.overflowIcon = overflowIcon

TRY THIS.

Finally the below line worked for me (after 2 days of trial and error -_-)

mBinding.toolbar.menu?.findItem(R.id.menu)?.icon?.setTint(Color.WHITE)
Eonism answered 5/7, 2021 at 22:20 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.