Java 如何在新材质主题中更改后退箭头的颜色?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/26788464/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-11 03:16:52  来源:igfitidea点击:

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

javaandroiduser-interfacecolorsandroid-styles

提问by Ferran Maylinch

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

我已将我的 SDK 更新为 API 21,现在备份/备份图标是一个指向左侧的黑色箭头。

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.

例如,在 Play 商店中,箭头是白色的。

I've done this to set some styles. I have used @drawable/abc_ic_ab_back_mtrl_am_alphafor 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_arrowand use it for homeAsUpIndicator.

我这样做是为了设置一些样式。我已经使用@drawable/abc_ic_ab_back_mtrl_am_alphahomeAsUpIndicator。该 drawable 是透明的(只有 alpha),但箭头显示为黑色。我想知道我是否可以像在DrawerArrowStyle. 或者,如果唯一的解决方案是创建 my@drawable/grey_arrow并将其用于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_textlike in DrawerArrowStyle.

到目前为止,我的解决方案是使用@drawable/abc_ic_ab_back_mtrl_am_alpha看起来是白色的 ,并使用照片编辑器将其绘制成我想要的颜色。它有效,尽管我更@color/actionbar_text喜欢在DrawerArrowStyle.

采纳答案by 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:

修订版 1:

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

从 API 23 (Marshmallow) 开始,可绘制资源abc_ic_ab_back_mtrl_am_alpha更改为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);

回答by Flávio Faria

Just remove android:homeAsUpIndicatorand homeAsUpIndicatorfrom your theme and it will be fine. The colorattribute in your DrawerArrowStylestyle must be enough.

只需从您的主题中删除android:homeAsUpIndicatorhomeAsUpIndicator就可以了。colorDrawerArrowStyle样式中的属性必须足够。

回答by Ferran Maylinch

Unless there's a better solution...

除非有更好的解决方案...

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

我所做的是拍摄@drawable/abc_ic_ab_back_mtrl_am_alpha看起来是白色的图像,然后使用照片编辑器将它们涂成我想要的颜色。

回答by rockgecko

Looking at the Toolbarand TintManagersource, drawable/abc_ic_ab_back_mtrl_am_alphais tinted with the value of the style attribute colorControlNormal.

查看ToolbarTintManager来源,drawable/abc_ic_ab_back_mtrl_am_alpha带有样式属性的值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.

我确实尝试在我的项目中设置它(<item name="colorControlNormal">@color/my_awesome_color</item>在我的主题中),但对我来说它仍然是黑色的。

Update:

更新

Found it. You need to set the actionBarThemeattribute (notactionBarStyle) with colorControlNormal.

找到了。您需要设置的actionBarTheme属性(actionBarStyle)用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>

回答by GFred

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:

我找到了一个在 Lollipop 之前有效的解决方案。在“actionBarWidgetTheme”中设置“colorControlNormal”来改变homeAsUpIndicator的颜色。从上面修改rockgecko的答案如下:

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

回答by Neo

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.

将此 toolbar_theme 应用到您的工具栏。

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>

回答by 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());

回答by Harry Aung

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

尝试了以上所有建议。我设法更改工具栏中导航图标默认后退按钮箭头颜色的唯一方法是在基本主题中设置 colorControlNormal 像这样。可能是因为父级正在使用 Theme.AppCompat.Light.NoActionBar

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

回答by Vinay W

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

另一个可能对您有用的解决方案是不将您的工具栏声明为应用程序的操作栏( bysetActionBarsetSupportActionBar),并使用本页另一个答案中提到的代码在您的 onActivityCreated 中设置后退图标

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 onOptionItemSelectedcallback when you press the back button. However, you can register for that using setNavigationOnClickListener. This is what i do:

现在,onOptionItemSelected当您按下后退按钮时,您将不会收到回调。但是,您可以使用setNavigationOnClickListener. 这就是我所做的:

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.

如果您使用菜单项,我不确定它是否会起作用。

回答by 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

Carles 的答案是正确的答案,但在我写这个答案时,很少有像getDrawable()、getColor()这样的方法被弃用。所以更新的答案是

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

在其他一些stackoverflow查询之后,我发现调用ContextCompat.getDrawable()类似于

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

ContextCompat.getColor()类似

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

链接 1:ContextCompat.getDrawable()

Link 2: ContextCompat.getColor()

链接 2:ContextCompat.getColor()