如何在新的材料主题中更改返回箭头的颜色?

211

我已将我的SDK更新到API 21,现在返回/向上的图标是一个指向左边的黑色箭头。

Black back arrow

我希望它是灰色的。我该怎么做?

例如,在Play商店中,该箭头为白色。

我已经这样做来设置一些样式。我使用了@drawable/abc_ic_ab_back_mtrl_am_alpha作为homeAsUpIndicator。该drawable是透明的(只有alpha),但箭头显示为黑色。 我想知道是否可以像在DrawerArrowStyle中那样设置颜色。或者,唯一的解决方案是创建我的@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>

到目前为止,我的解决方案是使用@drawable/abc_ic_ab_back_mtrl_am_alpha,它似乎是白色的,并使用照片编辑器将其涂成我想要的颜色。虽然这个方法可行,但我更希望像DrawerArrowStyle一样使用@color/actionbar_text


到目前为止,所有基于XML的答案都没有解决我的问题,但我已经成功地使用了您的“homeAsUpIndicator”/“@drawable/abc_ic_ab_back_mtrl_am_alpha”代码,使返回箭头变为白色。我更喜欢这种方法,而不是去修改Java代码。 - ban-geoengineering
旧但仍然有效。你使用的是ActionBar还是新的Toolbar? - f470071
默认的工具栏应该是有点灰色的,可以在工具栏的XML标签中使用android:theme="@style/Widget.AppCompat.Light.ActionBar"。它的颜色是#737373。 - android developer
检查一下我的答案 - 它非常简单,没有任何副作用。 - Sakiboy
25个回答

371

您可以通过代码实现。获取返回箭头的可绘制对象,使用过滤器修改其颜色,并将其设置为返回按钮。

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

修订 1:

从 API 23(Marshmallow)开始,可绘制资源 abc_ic_ab_back_mtrl_am_alpha 已更改为 abc_ic_ab_back_material

编辑:

您可以使用此代码来实现您想要的结果:

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

4
这是我尝试过,而不改变其他使用colorControlNormal颜色的小部件的色调时,唯一有效的方法。 - Joris
4
这个解决方案的问题在于它会将所有的返回箭头都涂成同样的颜色,如果你只想改变其中一个并让其他的保持为白色,则无法实现。 - dabluck
27
可以。请注意使用ContextCompat.getDrawable(this, R.drawable.abc_ic_ab_back_mtrl_am_alpha),因为getResources.getDrawable(int)已经被弃用。 - mrroboaat
4
另一个可能的解决方案是让您自己获取该资源并将其放入您的drawable文件夹中 :) - Mauker
12
请注意,在支持库23.2.0中,abc_ic_ab_back_mtrl_am_alpha已更改为abc_ic_ab_back_material。 - Jon
显示剩余15条评论

213

查看 ToolbarTintManager 源码,drawable/abc_ic_ab_back_mtrl_am_alpha 使用样式属性 colorControlNormal 的值进行了色调处理。

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

更新:

找到了。您需要使用 actionBarTheme 属性(不是 actionBarStyle)设置 colorControlNormal

例如:

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

4
这应该是被接受的答案。谢谢您。问题是,我找不到用于着色SearchView展开时显示的箭头的样式。有什么线索吗?显然这个答案对它没有影响。 - Daniel Ochoa
6
我需要添加 <item name="android:colorControlNormal">...</item>,并带有 android: 前缀。 - Seraphim's
7
很遗憾,这是一个 21 级的 API,如果你想支持低于此级别的任何内容,它将无法正常工作。 - gphilip
14
如果你的父主题源自于"NoActionBar"主题之一,那么在根主题上设置colorControlNormal而不是在actionBarTheme中设置是正确的做法。 - Jason Robinson
3
只用了2个小时的搜索、失败和再次搜索,我终于找到了这个方法。有时候安卓系统中的样式'系统'会把我逼疯! 当你有一个活动页面与其他页面不使用相同的样式时,使用这种方法尤为重要。 - Bron Davies
显示剩余3条评论

127
尝试上述所有建议。我设法改变工具栏中导航图标默认的返回按钮箭头的颜色的唯一方法是像这样在基本主题中设置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>

6
最简单的回答是,在不纠结其他代码的情况下,只需在你的 style.xml 文件中添加这一行即可。 - Rohan Kandwal
3
请记住,colorControlNormal 需要 API 21。 - Adnan Ali
3
如果你使用的是AppCompat,它也可以在API 21以下的版本上工作。显然,在这里使用了AppCompat,因为colorControlNormal没有以android:为前缀。 - Vicky Chijwani
6
但这也会改变其他小部件的色调...有没有办法不影响其他小部件,比如复选框和单选按钮? - Bruce
3
但这也会改变其他控件的颜色,比如单选按钮和文本编辑框下方的线条。 - olfek
显示剩余3条评论

70

需要将一个属性添加到您的工具栏主题中 -

<style name="toolbar_theme" parent="@style/ThemeOverlay.AppCompat.Dark.ActionBar">
    <item name="colorControlNormal">@color/arrow_color</item>
</style>
将此工具栏主题应用于您的工具栏。 或者 您可以直接应用于您的主题 -
<style name="CustomTheme" parent="Theme.AppCompat.Light.NoActionBar">
  <item name="colorControlNormal">@color/arrow_color</item> 
  //your code ....
</style>

5
尝试使用被广泛认可的答案(可能是网络上最流行的解决方案)对我来说不起作用,但是这个解决方案起作用了 :) 在与Android编程时感觉如此疯狂。 - King King
5
最简单的回答是:这样做不会改变其他控制主题。你只需要将自定义工具栏主题设置为你的工具栏即可。 :) - SimplyProgrammer
1
哦,你必须经历多少痛苦才能改变一个图标的颜色啊...第一个对我有效。第二个适用于自定义工具栏(以及其他一些东西)。三年后,感谢Neo。 - Aba

46

只需添加

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

适用于您当前的应用程序主题。


2
这会同时改变android.support.v7.widget.AppCompatCheckBox的颜色。 - Udi Oshi

37

如果使用Toolbar,你可以尝试这个。

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

这应该是被接受的答案,在我看来 - 它只针对箭头,使用最简单的方法设置箭头,并且也兼容API 21以下。 - Antek
如果你需要更多的自定义解决方案(在我的情况下是标题和菜单图标的不同颜色),那么这就是你想要的解决方案。 - TheJudge
3
请注意,在尝试调用getNavigationIcon()之前,您可能需要调用以下代码:getSupportActionBar().setDisplayHomeAsUpEnabled(true); 这将使返回箭头显示在应用程序栏中。 - rrbrambley
最佳答案!谢谢。 - shariful islam

34

正如之前大部分评论中所说的,解决方案是在你的应用主题中添加

<item name="colorControlNormal">@color/white</item> 但要确认在你的布局中Toolbar元素没有定义另一个主题。

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

3
太棒了!我尝试了所有关于将其添加到主题中的答案,但都没有效果... 正如你所提到的,我的工具栏中有android:theme="@style/ThemeOverlay.AppCompat.ActionBar"属性。一旦我将其移除,它就开始起作用了。 - Rahul Hawge

10

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

在查看一些其他StackOverflow问题后,我发现调用 ContextCompat.getDrawable() 类似于

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

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

链接1: ContextCompat.getDrawable()

链接2: ContextCompat.getColor()


应该使用abc_ic_ab_back_material,而不是abc_ic_ab_back_mtrl_am_alpha - Narendra Singh

7

我找到了一个在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>

7

在此输入图片描述

更改菜单导航图标颜色

最终转换菜单图标颜色

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

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接