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

╄→гoц情女王★ 提交于 2019-11-26 14:03:11
Carles

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);

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>

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>

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>

Just add

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

to your current app theme.

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" />

if use Toolbar,you can try this

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

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()

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>
Jumpa

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());

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>

Change Menu Nav 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>
Vinay Wadhwa

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.

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" />

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);

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;
}

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">

Simple solution that worked for me (if you need to use the same arrow color all across the app):

  1. Save the arrow icon that you'd like to use to the drawable folder (make sure it has the desired color; you can change your color in xml if you use xml vector drawable).

  2. Assign this new arrow icon to the action bar:

    ActionBar actionBar = getSupportActionBar(); actionBar.setHomeAsUpIndicator(R.drawable.ic_your_icon_here);

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

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.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!