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


193

我已经将SDK更新为API 21,现在“后退/向上”图标是一个指向左侧的黑色箭头。

黑色后退箭头

我希望它是灰色的。我怎样才能做到这一点?

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

我这样做是为了设置一些样式。我已经习惯@drawable/abc_ic_ab_back_mtrl_am_alphahomeAsUpIndicator。该可绘制对象是透明的(仅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>

到目前为止,我的解决方案是采用@drawable/abc_ic_ab_back_mtrl_am_alpha似乎是白色的,并使用照片编辑器将其绘制为所需的颜色。它可以工作,尽管我更喜欢在中使用@color/actionbar_textlike DrawerArrowStyle


到目前为止,没有基于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开发人员

Answers:


354

您可以通过代码来实现。获取可绘制的后退箭头,使用滤镜修改其颜色,并将其设置为后退按钮。

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(棉花糖)开始,可绘制资源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

24
有用。请注意,您应该使用ContextCompat.getDrawable(this, R.drawable.abc_ic_ab_back_mtrl_am_alpha)因为getResources.getDrawable(int)已弃用
mrroboaat 2015年

3
另一个可能的解决方案是让您自己获取资源并将其放在可绘制的文件夹中:)
Mauker 2015年

12
请注意,在23.2.0支持库中,abc_ic_ab_back_mtrl_am_alpha更改为abc_ic_ab_back_material
Jon

206

看着ToolbarTintManager源,drawable/abc_ic_ab_back_mtrl_am_alpha用style属性的值进行着色colorControlNormal

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

更新

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

例如:

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

6
我还需要添加<item name =“ android:colorControlNormal”> ... </ item>和android:前缀
塞拉芬

7
不幸的是,这是21级API,如果您要支持低于它的任何功能,将无法正常工作。
gphilip

10
如果您的父主题是从“ NoActionBar”主题之一衍生而来的,那么设置colorControlNormal根主题而不是中的主题actionBarTheme是可行的方法。
杰森·罗宾逊

3
我只花了2个小时的搜索,失败和再次搜索就终于做到了。有时,Android中的样式“系统”会让我发疯!当您的一项活动没有使用与其他活动相同的样式时,使用此方法尤为重要。
布朗·戴维斯

118

尝试了以上所有建议。我设法在工具栏中更改导航图标默认后退按钮箭头颜色的唯一方法是在基本主题中设置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 2015年

3
记住colorControlNormal需要API 21
Adnan Ali

3
@AdnanAli(如果您使用的是AppCompat)也可以在<API 21上使用。显然,程序兼容性在这里被使用,因为colorControlNormal没有前缀android:
Vicky Chijwani

3
但这也改变了所有其他小部件的色彩。是否有不影响复选框和单选按钮等其他小部件的方式?
布鲁斯

2
但这也会更改其他控件的颜色,例如单选按钮和文本编辑下的行。
达卡

66

需要向工具栏主题添加一个属性-

<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

4
最简单的答案。这无需更改其他控制主题即可起作用。您只需要将自定义工具栏主题设置为工具栏。:)
SimplyProgrammer

1
哦,您只需要更改一个图标的颜色就需要经历的艰辛。第一个图标对我有用。第二个适用于自定义工具栏(显然其他功能也适用)。3年后,非常感谢Neo。
阿坝州

45

只需添加

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

您当前的应用主题。


2
这也改变了android.support.v7.widget.AppCompatCheckBox的颜色
Udi Oshi

34

如果使用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

最好的答案!谢谢。
伊斯兰教徒伊斯兰教

32

如之前的大多数评论所述,解决方案是添加

<item name="colorControlNormal">@color/white</item> 您的应用主题。但是请确认您在布局上的工具栏元素中没有定义其他主题。

     <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
纳伦德拉·辛格

7

我找到了可以在棒棒糖之前使用的解决方案。在“ 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

在compileSdkVersoin 25上,您可以执行以下操作:

styles.xml

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

6

使用以下方法:

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

现在,您可以使用以下命令设置可绘制对象:

getSupportActionBar().setHomeAsUpIndicator(getColoredArrow());

6

在此处输入图片说明

更改菜单导航图标颜色

最终转换菜单图标颜色

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

5

可能对您有用的另一种解决方案是不将工具栏声明为应用程序的操作栏(通过setActionBarsetSupportActionBar),并使用此页面上另一个答案中提到的代码在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);

现在,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
    }
});

我不确定如果您使用菜单项是否可以使用。


3

我们遇到了同样的问题,我们所要做的就是设置

app:collapseIcon

最后在工具栏中的属性,我们没有找到它,因为它没有被很好地记录:)

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

3

试试这个

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

函数调用:

enableActionBarHomeButton(this, R.color.white);

设置{@link #DISPLAY_HOME_AS_UP}显示选项将自动启用主页按钮。
P. Savrov '17

2

这对我有用:

将以下属性添加到您的主题。

更改api 21上方的工具栏/操作栏后退箭头

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

要更改API 21下面的工具栏/操作栏后退箭头

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

更改动作模式后退箭头

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

删除工具栏/操作栏阴影

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

更改动作栏溢出可绘制

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

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

注意:由于对21以下的api的矢量可绘制支持,因此使用了“ srcCompat”而不是“ android:src”


1

我只是将工具栏主题更改为@ style / ThemeOverlay.AppCompat.Light

箭头变成深灰色

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

1

这是我在“材料组件”中的操作方式:

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

哥们,你救了我的一天。我只花了整整一天的时间。希望我能给你更多的选票。
Dhaval Patel

1

解决方法很简单

只需将以下行放入名为AppTheme的样式中

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

现在,您的整个xml代码将如下所示(默认样式)。

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

0

您可以通过编程方式更改导航图标的颜色,如下所示:

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

-1

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


我已经尝试过了,箭头是黑色的。请注意,此箭头与打开抽屉时看到的箭头不同(该箭头受color属性影响)。抽屉箭头较大。
Ferran Maylinch 2014年

1
因此,似乎您必须提供自己的可绘制资源。:您可以使用此工具生成它shreyasachar.github.io/AndroidAssetStudio
弗拉维奥法里亚

-4

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

我要做的是@drawable/abc_ic_ab_back_mtrl_am_alpha拍摄看起来是白色的图像,然后使用照片编辑器将其绘制为我想要的颜色。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.