How to change color of the back arrow in the new material theme?

JavaAndroidUser InterfaceColorsAndroid Styles

Java Problem Overview


I've updated my SDK to API 21 and now the back/up icon is a black arrow pointing to the left.

Black back arrow

I would like it to be grey. How can I do that?

In the Play Store, for example, the arrow is white.

I've done this to set some styles. I have used @drawable/abc_ic_ab_back_mtrl_am_alpha for homeAsUpIndicator. That drawable is transparent (only alpha) but the arrow is displayed in black. I wonder if I can set the color like I do in the DrawerArrowStyle. Or if the only solution is to create my @drawable/grey_arrow and use it for homeAsUpIndicator.

<!-- Base application theme -->
<style name="AppTheme" parent="Theme.AppCompat.Light">

    <item name="android:actionBarStyle" tools:ignore="NewApi">@style/MyActionBar</item>
    <item name="actionBarStyle">@style/MyActionBar</item>

    <item name="drawerArrowStyle">@style/DrawerArrowStyle</item>

    <item name="homeAsUpIndicator">@drawable/abc_ic_ab_back_mtrl_am_alpha</item>
    <item name="android:homeAsUpIndicator" tools:ignore="NewApi">@drawable/abc_ic_ab_back_mtrl_am_alpha</item>
</style>

<!-- ActionBar style -->
<style name="MyActionBar" parent="@style/Widget.AppCompat.Light.ActionBar.Solid">

    <item name="android:background">@color/actionbar_background</item>
    <!-- Support library compatibility -->
    <item name="background">@color/actionbar_background</item>
</style>

<!-- Style for the navigation drawer icon -->
<style name="DrawerArrowStyle" parent="Widget.AppCompat.DrawerArrowToggle">
    <item name="spinBars">true</item>
    <item name="color">@color/actionbar_text</item>
</style>

My solution so far has been to take the @drawable/abc_ic_ab_back_mtrl_am_alpha, which seems to be white, and paint it in the color I desire using a photo editor. It works, although I would prefer to use @color/actionbar_text like in DrawerArrowStyle.

Java Solutions


Solution 1 - Java

You can achieve it through code. Obtain the back arrow drawable, modify its color with a filter, and set it as back button.

final Drawable upArrow = getResources().getDrawable(R.drawable.abc_ic_ab_back_mtrl_am_alpha);
upArrow.setColorFilter(getResources().getColor(R.color.grey), PorterDuff.Mode.SRC_ATOP);
getSupportActionBar().setHomeAsUpIndicator(upArrow);

Revision 1:

Starting from API 23 (Marshmallow) the drawable resource abc_ic_ab_back_mtrl_am_alpha is changed to abc_ic_ab_back_material.

EDIT:

You can use this code to achieve the results you want:

toolbar.getNavigationIcon().setColorFilter(getResources().getColor(R.color.blue_gray_15), PorterDuff.Mode.SRC_ATOP);

Solution 2 - Java

Looking at the Toolbar and TintManager source, drawable/abc_ic_ab_back_mtrl_am_alpha is tinted with the value of the style attribute colorControlNormal.

I did try setting this in my project (with <item name="colorControlNormal">@color/my_awesome_color</item> in my theme), but it's still black for me.

Update:

Found it. You need to set the actionBarTheme attribute (not actionBarStyle) with colorControlNormal.

Eg:

<style name="MyTheme" parent="Theme.AppCompat.Light">        
    <item name="actionBarTheme">@style/MyApp.ActionBarTheme</item>
    <item name="actionBarStyle">@style/MyApp.ActionBar</item>
    <!-- color for widget theming, eg EditText. Doesn't effect ActionBar. -->
    <item name="colorControlNormal">@color/my_awesome_color</item>
    <!-- The animated arrow style -->
    <item name="drawerArrowStyle">@style/DrawerArrowStyle</item>
</style>

<style name="MyApp.ActionBarTheme" parent="@style/ThemeOverlay.AppCompat.ActionBar">       
    <!-- THIS is where you can color the arrow! -->
    <item name="colorControlNormal">@color/my_awesome_color</item>
</style>

<style name="MyApp.ActionBarStyle" parent="@style/Widget.AppCompat.Light.ActionBar">
    <item name="elevation">0dp</item>      
    <!-- style for actionBar title -->  
    <item name="titleTextStyle">@style/ActionBarTitleText</item>
    <!-- style for actionBar subtitle -->  
    <item name="subtitleTextStyle">@style/ActionBarSubtitleText</item>

    <!-- 
    the actionBarTheme doesn't use the colorControlNormal attribute
    <item name="colorControlNormal">@color/my_awesome_color</item>
     -->
</style>

Solution 3 - Java

Tried all suggestions above. The only way that I managed to change the color of navigation icon default Back button arrow in my toolbar is to set colorControlNormal in base theme like this. Probably due to the fact that the parent is using Theme.AppCompat.Light.NoActionBar

<style name="BaseTheme" parent="Theme.AppCompat.Light.NoActionBar">
  <item name="colorControlNormal">@color/white</item> 
  //the rest of your codes...
</style>

Solution 4 - Java

Need to add a single attribute to your toolbar theme -

<style name="toolbar_theme" parent="@style/ThemeOverlay.AppCompat.Dark.ActionBar">
    <item name="colorControlNormal">@color/arrow_color</item>
</style>

Apply this toolbar_theme to your toolbar.

OR

you can directly apply to your theme -

<style name="CustomTheme" parent="Theme.AppCompat.Light.NoActionBar">
  <item name="colorControlNormal">@color/arrow_color</item> 
  //your code ....
</style>

Solution 5 - Java

Just add

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

to your current app theme.

Solution 6 - Java

if use Toolbar,you can try this

Drawable drawable = toolbar.getNavigationIcon();
drawable.setColorFilter(ContextCompat.getColor(appCompatActivity, colorId), PorterDuff.Mode.SRC_ATOP);

Solution 7 - Java

As said on most of the previous comments, the solution is to add

<item name="colorControlNormal">@color/white</item> to your app theme. But confirm that you don´t have another theme defined in your Toolbar element on your layout.

     <android.support.v7.widget.Toolbar
            android:id="@+id/toolbar"
            android:layout_width="match_parent"
            android:layout_height="?attr/actionBarSize"
            android:background="?attr/colorPrimary"
            android:elevation="4dp"
            android:theme="@style/ThemeOverlay.AppCompat.ActionBar"
            app:popupTheme="@style/ThemeOverlay.AppCompat.Light" />

Solution 8 - Java

The answer by Carles is the correct answer, but few of the methods like getDrawable(), getColor() got deprecated at the time I am writing this answer. So the updated answer would be

Drawable upArrow = ContextCompat.getDrawable(context, R.drawable.abc_ic_ab_back_mtrl_am_alpha);
upArrow.setColorFilter(ContextCompat.getColor(context, R.color.white), PorterDuff.Mode.SRC_ATOP);
getSupportActionBar().setHomeAsUpIndicator(upArrow);

Following some other stackoverflow queries I found that calling ContextCompat.getDrawable() is similar to

if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
    return resources.getDrawable(id, context.getTheme());
} else {
    return resources.getDrawable(id);
}

And ContextCompat.getColor() is similar to

public static final int getColor(Context context, int id) {
    final int version = Build.VERSION.SDK_INT;
    if (version >= 23) {
        return ContextCompatApi23.getColor(context, id);
    } else {
        return context.getResources().getColor(id);
    }
}

Link 1: ContextCompat.getDrawable()

Link 2: ContextCompat.getColor()

Solution 9 - Java

I found a solution that works pre Lollipop. Set the "colorControlNormal" within the "actionBarWidgetTheme" to change the homeAsUpIndicator color. Modifying rockgecko's answer from above to look like this:

<style name="MyTheme" parent="Theme.AppCompat.Light">        
    <item name="actionBarTheme">@style/MyApp.ActionBarTheme</item>
    <item name="actionBarStyle">@style/MyApp.ActionBar</item>
    <!-- color for widget theming, eg EditText. Doesn't effect ActionBar. -->
    <item name="colorControlNormal">@color/my_awesome_color</item>
    <!-- The animated arrow style -->
    <item name="drawerArrowStyle">@style/DrawerArrowStyle</item>
    <!-- The style for the widgets on the ActionBar. -->
    <item name="actionBarWidgetTheme">@style/WidgetStyle</item>
</style>

<style name="WidgetStyle" parent="style/ThemeOverlay.AppCompat.Light">
    <item name="colorControlNormal">@color/my_awesome_color</item>
</style>

Solution 10 - Java

On compileSdkVersoin 25, you could do this:

styles.xml

<style name="AppTheme" parent="Theme.AppCompat.Light">
     <item name="android:textColorSecondary">@color/your_color</item>
</style>

Solution 11 - Java

enter image description here

Change Menu Nav Icon Color

Final convert Menu Icon Color

In style.xml :

<style name="MyMaterialTheme.Base" parent="Theme.AppCompat.Light.DarkActionBar">
    <item name="windowNoTitle">true</item>
    <item name="windowActionBar">false</item>
    <item name="colorPrimary">@color/colorPrimary</item>
    <item name="colorPrimaryDark">@color/colorPrimaryDark</item>
    <item name="colorAccent">@color/colorAccent</item>
    <item name="drawerArrowStyle">@style/DrawerArrowStyle</item>
    <item name="android:textColor">@color/colorAccent</item>


</style>

<style name="DrawerArrowStyle" parent="@style/Widget.AppCompat.DrawerArrowToggle">
    <item name="spinBars">true</item>
    <item name="color">@color/colorPrimaryDark</item>
</style>







In Mainfests.xml :

<activity android:name=".MainActivity"
        android:theme="@style/MyMaterialTheme.Base"></activity>

Solution 12 - Java

Use below method:

private Drawable getColoredArrow() {
    Drawable arrowDrawable = getResources().getDrawable(R.drawable.abc_ic_ab_back_mtrl_am_alpha);
    Drawable wrapped = DrawableCompat.wrap(arrowDrawable);

    if (arrowDrawable != null && wrapped != null) {
        // This should avoid tinting all the arrows
        arrowDrawable.mutate();
        DrawableCompat.setTint(wrapped, Color.GRAY);
    }

    return wrapped;
}

Now you can set the drawable with:

getSupportActionBar().setHomeAsUpIndicator(getColoredArrow());

Solution 13 - Java

Solution is very simple

Just put following line into your style named as AppTheme

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

Now your whole xml code will look like shown below (default style).

<style name="AppTheme" parent="Theme.AppCompat.Light.NoActionBar">

        <item name="colorPrimary">#0F0F0F</item>
        <item name="android:statusBarColor">#EEEEF0</item>
        <item name="android:windowLightStatusBar">true</item>
        <item name="colorAccent">@color/colorAccent</item>
        <item name="android:windowActivityTransitions">true</item>

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

Solution 14 - Java

Another solution that might work for you is to not declare your toolbar as the app's action bar ( by setActionBar or setSupportActionBar ) and set the back icon in your onActivityCreated using the code mentioned in another answer on this page

final Drawable upArrow = getResources().getDrawable(R.drawable.abc_ic_ab_back_mtrl_am_alpha);
upArrow.setColorFilter(getResources().getColor(R.color.grey), PorterDuff.Mode.SRC_ATOP);
toolbar.setNavigationIcon(upArrow);

Now, you will not get the onOptionItemSelected callback when you press the back button. However, you can register for that using setNavigationOnClickListener. This is what i do:

toolbar.setNavigationOnClickListener(new View.OnClickListener() {
    @Override
    public void onClick(View view) {
        getActivity().onBackPressed(); //or whatever you used to do on your onOptionItemSelected's android.R.id.home callback
    }
});

I'm not sure if it will work if you work with menu items.

Solution 15 - Java

This is what worked for me:

Add the below attributes to your theme.

To change toolbar/actionbar back arrow above api 21

<item name="android:homeAsUpIndicator">@drawable/your_drawable_icon</item>

To change toolbar/actionbar back arrow below api 21

<item name="homeAsUpIndicator">@drawable/your_drawable_icon</item>

To change action mode back arrow

<item name="actionModeCloseDrawable">@drawable/your_drawable_icon</item>

To remove toolbar/actionbar shadow

<item name="android:elevation" tools:targetApi="lollipop">0dp</item>
<item name="elevation">0dp</item>
<!--backward compatibility-->
<item name="android:windowContentOverlay">@null</item>

To change actionbar overflow drawable

<!--under theme-->
<item name="actionOverflowButtonStyle">@style/MenuOverflowStyle</item>

<style name="MenuOverflowStyle" parent="Widget.AppCompat.ActionButton.Overflow">
<item name="srcCompat">@drawable/ic_menu_overflow</item>

Note : 'srcCompat' is used instead of 'android:src' because of vector drawable support for api below 21

Solution 16 - Java

Here's how I did it in Material Components:

<style name="AppTheme" parent="Theme.MaterialComponents.DayNight.NoActionBar">
    <item name="drawerArrowStyle">@style/AppTheme.DrawerArrowToggle</item>
</style>

<style name="AppTheme.DrawerArrowToggle" parent="Widget.AppCompat.DrawerArrowToggle">
    <item name="color">@android:color/white</item>
</style>

Solution 17 - Java

We were running into the same problem and all we wanted was to set the

app:collapseIcon

attribute in the toolbar in the end, which we did not find since it is not very well documented :)

<android.support.v7.widget.Toolbar
         android:id="@+id/toolbar"
         android:layout_width="match_parent"
         android:layout_height="@dimen/toolbarHeight"
         app:collapseIcon="@drawable/collapseBackIcon" />

Solution 18 - Java

try this

public void enableActionBarHomeButton(AppCompatActivity appCompatActivity, int colorId){

    final Drawable upArrow = ContextCompat.getDrawable(appCompatActivity, R.drawable.abc_ic_ab_back_material);
    upArrow.setColorFilter(ContextCompat.getColor(appCompatActivity, colorId), PorterDuff.Mode.SRC_ATOP);

    android.support.v7.app.ActionBar mActionBar = appCompatActivity.getSupportActionBar();
    mActionBar.setHomeAsUpIndicator(upArrow);
    mActionBar.setHomeButtonEnabled(true);
    mActionBar.setDisplayHomeAsUpEnabled(true);
}

function call:

enableActionBarHomeButton(this, R.color.white);

Solution 19 - Java

I just changed the toolbar theme to be @style/ThemeOverlay.AppCompat.Light

and the arrow became dark gray

            <android.support.v7.widget.Toolbar
            android:id="@+id/toolbar"
            android:layout_width="match_parent"
            android:layout_height="?attr/actionBarSize"
            android:gravity="center"
            app:layout_collapseMode="pin"
            app:theme="@style/ThemeOverlay.AppCompat.Light">

Solution 20 - Java

The simplest (and best) way to change the color of the back/up-arrow. Best part is that there are no side-effects (unlike the other answers)!

  • Create a style with parent Widget.AppCompat.DrawerArrowToggle, define the color and any other attributes you'd like.
  • Set the style on the drawerArrowStyle attribute in the apps Theme.

Create style:

<style name="DrawerArrowStyle" parent="Widget.AppCompat.DrawerArrowToggle">
    <!--        Set that the nav buttons will animate-->
    <item name="spinBars">true</item>
    <!--        Set the color of the up arrow / hamburger button-->
    <item name="color">@color/white</item>
</style>

Set the style in App Theme:

<!-- Base application theme. -->
<style name="AppTheme" parent="Theme.MaterialComponents.Light.NoActionBar">
    <item name="colorPrimary">@color/colorPrimary</item>
    <item name="colorPrimaryDark">@color/colorPrimaryDark</item>
    <item name="colorAccent">@color/colorAccent</item>

    <!--  Change global up-arrow color with no side-effects    -->
    <item name="drawerArrowStyle">@style/DrawerArrowStyle</item>
</style>

To change the ToolBar text color (and other attributes), create this style:

<style name="ToolbarStyle" parent="Widget.AppCompat.Toolbar">
    <item name="android:textColor">@color/white</item>
    <item name="titleTextColor">@color/white</item>
    <item name="colorControlNormal">@color/white</item> <!-- colorControlNormal is Probably not necessary    -->
</style>

Then set that style on the AppTheme:

<!-- Base application theme. -->
<style name="AppTheme.MyProduceApp" parent="Theme.MaterialComponents.Light.NoActionBar.Bridge">
    <item name="colorPrimary">@color/colorPrimary</item>
    <item name="colorPrimaryDark">@color/colorPrimaryDark</item>
    <item name="colorAccent">@color/colorAccent</item>

    <!--  Style the toolbar (mostly the color of the text) -->
    <item name="toolbarStyle">@style/ToolbarStyle</item>
    <!--  Change color of up-arrow    -->
    <item name="drawerArrowStyle">@style/DrawerArrowStyle</item>
</style>

Solution 21 - Java

You can change the color of the navigation icon programmatically like this:

mToolbar.setNavigationIcon(getColoredArrow()); 

private Drawable getColoredArrow() {
        Drawable arrowDrawable = getResources().getDrawable(R.drawable.abc_ic_ab_back_mtrl_am_alpha);
        Drawable wrapped = DrawableCompat.wrap(arrowDrawable);

        if (arrowDrawable != null && wrapped != null) {
            // This should avoid tinting all the arrows
            arrowDrawable.mutate();
                DrawableCompat.setTintList(wrapped, ColorStateList.valueOf(this.getResources().getColor(R.color.your_color)));
            }
        }

        return wrapped;
}

Solution 22 - Java

private fun setToolbarNavigationIconColor(context: Context, toolbar: Toolbar?, color: Int) {
    val drawableBack = toolbar?.navigationIcon
    drawableBack?.let {
        val drawableWrap = DrawableCompat.wrap(drawableBack).mutate()
        DrawableCompat.setTint(
            drawableWrap, ContextCompat.getColor(context, white)
        )
        toolbar.navigationIcon = drawableWrap
    }
}

Solution 23 - Java

I saw all soluation but didn't fix the problem , If you need fix the problem just add in XMl file this code if you but dark make it light

 app:theme="@style/ThemeOverlay.AppCompat.Light"

Solution 24 - Java

Just remove android:homeAsUpIndicator and homeAsUpIndicator from your theme and it will be fine. The color attribute in your DrawerArrowStyle style must be enough.

Solution 25 - Java

Unless there's a better solution...

What I did is to take the @drawable/abc_ic_ab_back_mtrl_am_alpha images, which seem to be white, and paint them in the color I desire using a photo editor.

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionFerran MaylinchView Question on Stackoverflow
Solution 1 - JavaCarlesView Answer on Stackoverflow
Solution 2 - JavarockgeckoView Answer on Stackoverflow
Solution 3 - JavaHarry AungView Answer on Stackoverflow
Solution 4 - JavaNeoView Answer on Stackoverflow
Solution 5 - JavaS bruceView Answer on Stackoverflow
Solution 6 - JavalongbaobaoView Answer on Stackoverflow
Solution 7 - JavamanuelvscView Answer on Stackoverflow
Solution 8 - Javacapt.swagView Answer on Stackoverflow
Solution 9 - JavaGFredView Answer on Stackoverflow
Solution 10 - JavachrizonlineView Answer on Stackoverflow
Solution 11 - JavaSumit SaxenaView Answer on Stackoverflow
Solution 12 - JavaJumpaView Answer on Stackoverflow
Solution 13 - JavaSuyogView Answer on Stackoverflow
Solution 14 - JavaVinay WView Answer on Stackoverflow
Solution 15 - JavaSadashivView Answer on Stackoverflow
Solution 16 - JavaSamView Answer on Stackoverflow
Solution 17 - JavaJulian HorstView Answer on Stackoverflow
Solution 18 - JavaSiddarth KantedView Answer on Stackoverflow
Solution 19 - JavafullmoonView Answer on Stackoverflow
Solution 20 - JavaSakiboyView Answer on Stackoverflow
Solution 21 - JavaPraveshView Answer on Stackoverflow
Solution 22 - JavaRamiView Answer on Stackoverflow
Solution 23 - JavaMohamed Mohamed TahaView Answer on Stackoverflow
Solution 24 - JavaFlávio FariaView Answer on Stackoverflow
Solution 25 - JavaFerran MaylinchView Answer on Stackoverflow