简体   繁体   English

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

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

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,现在后退/后退图标是一个指向左侧的黑色箭头。

黑背箭头

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_alpha for homeAsUpIndicator .我已将@drawable/abc_ic_ab_back_mtrl_am_alpha用于homeAsUpIndicator That drawable is transparent (only alpha) but the arrow is displayed in black.该drawable是透明的(只有alpha),但箭头显示为黑色。 I wonder if I can set the color like I do in the DrawerArrowStyle .我想知道我是否可以像在DrawerArrowStyle中那样设置颜色。 Or if the only solution is to create my @drawable/grey_arrow and use it for homeAsUpIndicator .或者,如果唯一的解决方案是创建我的@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.到目前为止,我的解决方案是采用似乎是白色的@drawable/abc_ic_ab_back_mtrl_am_alpha ,并使用照片编辑器将其绘制成我想要的颜色。 It works, although I would prefer to use @color/actionbar_text like in DrawerArrowStyle .它可以工作,尽管我更喜欢像在DrawerArrowStyle中那样使用@color/actionbar_text actionbar_text 。

You can achieve it through code.您可以通过代码来实现它。 Obtain the back arrow drawable, modify its color with a filter, and set it as back button.获取后退箭头drawable,用滤镜修改颜色,设置为后退按钮。

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

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 .查看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 actionBarTheme attribute ( not actionBarStyle ) with colorControlNormal .您需要使用colorControlNormal设置actionBarTheme属性(不是actionBarStyle )。

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.我设法更改工具栏中导航图标默认后退按钮箭头颜色的唯一方法是像这样在基本主题中设置 colorControlNormal。 Probably due to the fact that the parent is using Theme.AppCompat.Light.NoActionBar可能是因为父母正在使用 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.到您当前的应用主题。

if use Toolbar ,you can try this如果使用Toolbar ,你可以试试这个

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

As said on most of the previous comments, the solution is to add正如前面大多数评论所说,解决方案是添加

<item name="colorControlNormal">@color/white</item> to your app theme. <item name="colorControlNormal">@color/white</item>到您的应用主题。 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" />

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 . Carles 的答案是正确的答案,但在我写这个答案时,很少有像 getDrawable()、getColor() 这样的方法被弃用 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在其他一些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 toContextCompat.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()

I found a solution that works pre Lollipop.我找到了一个适用于 Lollipop 的解决方案。 Set the "colorControlNormal" within the "actionBarWidgetTheme" to change the homeAsUpIndicator color.在“actionBarWidgetTheme”中设置“colorControlNormal”以更改 homeAsUpIndicator 颜色。 Modifying rockgecko's answer from above to look like this:从上面修改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>

On compileSdkVersoin 25, you could do this:在 compileSdkVersoin 25 上,您可以这样做:

styles.xml样式.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.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>

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:现在你可以设置drawable:

getSupportActionBar().setHomeAsUpIndicator(getColoredArrow());

Solution is very simple解决方法很简单

Just put following line into your style named as AppTheme只需将以下行放入名为AppTheme的样式中

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

Now your whole xml code will look like shown below (default style).现在您的整个 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>

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另一个可能对您有用的解决方案是不将您的工具栏声明为应用程序的操作栏(通过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);

Now, you will not get the onOptionItemSelected callback when you press the back button.现在,当您按下后退按钮时,您将不会收到onOptionItemSelected回调。 However, you can register for that using setNavigationOnClickListener .但是,您可以使用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.如果您使用菜单项,我不确定它是否会起作用。

This is what worked for me:这对我有用:

Add the below attributes to your theme.将以下属性添加到您的主题中。

To change toolbar/actionbar back arrow above api 21更改 api 21 上方的工具栏/操作栏后退箭头

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

To change toolbar/actionbar back arrow below api 21更改 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注意:使用 'srcCompat' 代替 'android:src' 因为矢量可绘制支持低于 21 的 api

Here's how I did it in Material Components:以下是我在 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>

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

I just changed the toolbar theme to be @style/ThemeOverlay.AppCompat.Light我刚刚将工具栏主题更改为 @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">

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.使用父Widget.AppCompat.DrawerArrowToggle创建样式,定义color和您想要的任何其他属性。
  • Set the style on the drawerArrowStyle attribute in the apps Theme.在应用程序主题中的drawerArrowStyle属性上设置样式。

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:在 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 :要更改ToolBar文本颜色(和其他属性),请创建以下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:然后在 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>

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

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). 将您要使用的箭头图标保存到drawable文件夹(确保它具有所需的颜色;如果您使用xml矢量drawable,则可以在xml中更改颜色)。

  2. Assign this new arrow icon to the action bar: 将此新箭头图标指定给操作栏:

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

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

我看到了所有解决方案,但没有解决问题,如果您需要解决问题,只需在 XMl 文件中添加此代码,如果您将其变暗使其变亮

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

Just remove android:homeAsUpIndicator and homeAsUpIndicator from your theme and it will be fine.只需从您的主题中删除android:homeAsUpIndicatorhomeAsUpIndicator就可以了。 The color attribute in your DrawerArrowStyle style must be enough. DrawerArrowStyle样式中的color属性必须足够。

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.我所做的是获取@drawable/abc_ic_ab_back_mtrl_am_alpha图像,这些图像似乎是白色的,并使用照片编辑器将它们绘制成我想要的颜色。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM