Comment changer la couleur de la flèche arrière dans le nouveau thème de matériau?

193

J'ai mis à jour mon SDK vers l'API 21 et maintenant l'icône de sauvegarde / remontée est une flèche noire pointant vers la gauche.

Flèche arrière noire

J'aimerais que ce soit gris. Comment puis je faire ça?

Dans le Play Store, par exemple, la flèche est blanche.

J'ai fait cela pour définir certains styles. J'ai utilisé @drawable/abc_ic_ab_back_mtrl_am_alphapour homeAsUpIndicator. Ce dessinable est transparent (uniquement alpha) mais la flèche est affichée en noir. Je me demande si je peux définir la couleur comme je le fais dans le DrawerArrowStyle. Ou si la seule solution est de créer my @drawable/grey_arrowet de l'utiliser pour 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>

Jusqu'à présent, ma solution a été de prendre le @drawable/abc_ic_ab_back_mtrl_am_alpha, qui semble être blanc, et de le peindre dans la couleur que je désire à l'aide d'un éditeur de photos. Cela fonctionne, même si je préfère utiliser @color/actionbar_textcomme dans DrawerArrowStyle.

Ferran Maylinch
la source
Aucune des réponses basées sur XML jusqu'à présent n'a résolu ce problème pour moi, mais j'ai utilisé avec succès votre homeAsUpIndicator/ @drawable/abc_ic_ab_back_mtrl_am_alphacode pour rendre la flèche arrière blanche. Je préfère cela au piratage de Java.
ban-geoengineering
Vieux mais toujours. Utilisez-vous (utilisiez-vous) ActionBar ou la nouvelle barre d'outils?
f470071
La valeur par défaut est censée être un peu grise, en utilisant android: theme = "@ style / Widget.AppCompat.Light.ActionBar" dans la balise XML Toolbar. Sa couleur est # 737373
développeur android

Réponses:

354

Vous pouvez y parvenir grâce au code. Obtenez la flèche de retour dessinable, modifiez sa couleur avec un filtre et définissez-la comme bouton de retour.

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

Révision 1:

À partir de l'API 23 (Marshmallow), la ressource dessinable abc_ic_ab_back_mtrl_am_alphaest remplacée par abc_ic_ab_back_material.

ÉDITER:

Vous pouvez utiliser ce code pour obtenir les résultats souhaités:

toolbar.getNavigationIcon().setColorFilter(getResources().getColor(R.color.blue_gray_15), PorterDuff.Mode.SRC_ATOP);
Carles
la source
4
C'est la seule chose qui a fonctionné pour moi sans changer la teinte de tous les autres widgets avec colorControlNormal
Joris
4
Le problème avec cette solution est qu'elle peint toutes vos autres flèches arrière, si vous ne voulez en changer qu'une et laisser le reste blanc
dabluck
24
Ça marche. Veuillez noter que vous devriez utiliser ContextCompat.getDrawable(this, R.drawable.abc_ic_ab_back_mtrl_am_alpha)car getResources.getDrawable(int)est obsolète
mrroboaat
3
Une autre solution possible serait pour vous d'obtenir cette ressource vous-même et de la mettre dans vos dossiers dessinables :)
Mauker
12
Notez que abc_ic_ab_back_mtrl_am_alpha a été remplacé par abc_ic_ab_back_material dans la bibliothèque de support 23.2.0
Jon
206

En regardant la source Toolbaret TintManager, drawable/abc_ic_ab_back_mtrl_am_alphaest teintée avec la valeur de l'attribut style colorControlNormal.

J'ai essayé de définir cela dans mon projet (avec <item name="colorControlNormal">@color/my_awesome_color</item>dans mon thème), mais c'est toujours noir pour moi.

Mise à jour :

Je l'ai trouvé. Vous devez définir l' actionBarThemeattribut ( pas actionBarStyle ) avec colorControlNormal.

Par exemple:

<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>
rockgecko
la source
4
Cela devrait être la réponse acceptée. Merci pour ça. Question, je ne parviens pas à trouver le style de coloration de la flèche affichée lorsque SearchView est développé. Un indice? Il n'est apparemment pas affecté par cette réponse.
Daniel Ochoa
6
Je dois aussi ajouter <item name = "android: colorControlNormal"> ... </item> avec le préfixe android:
Seraphim's
7
Malheureusement, il s'agit d'une API de niveau 21 et si vous souhaitez prendre en charge quelque chose en dessous, cela ne fonctionnera pas.
gphilip
10
Si votre thème parent dérive de l'un des thèmes "NoActionBar", le réglage colorControlNormalsur le thème racine plutôt que sur le actionBarThemeest la voie à suivre.
Jason Robinson le
3
Il ne m'a fallu que 2 heures de recherche et d'échec et de recherche pour enfin y arriver. Parfois, le «système» de style dans Android me rend fou! Cette méthode est particulièrement importante à utiliser lorsque vous avez une activité qui n'utilise pas le même style que les autres.
Bron Davies
119

J'ai essayé toutes les suggestions ci-dessus. La seule façon dont j'ai réussi à changer la couleur de la flèche du bouton Retour par défaut de l'icône de navigation dans ma barre d'outils est de définir colorControlNormal dans le thème de base comme celui-ci. Probablement dû au fait que le parent utilise Theme.AppCompat.Light.NoActionBar

<style name="BaseTheme" parent="Theme.AppCompat.Light.NoActionBar">
  <item name="colorControlNormal">@color/white</item> 
  //the rest of your codes...
</style>
Harry Aung
la source
6
La réponse la plus simple de toutes, au lieu de jouer avec un autre code, ajoutez simplement cette ligne dans votrestyle.xml
Rohan Kandwal
3
rappelez-vous que colorControlNormal nécessite l'API 21
Adnan Ali
3
@AdnanAli si vous utilisez AppCompat, cela fonctionnera également sur <API 21. Clairement, AppCompat est utilisé ici car il colorControlNormaln'est pas préfixé par android:.
Vicky Chijwani
3
Mais cela modifie également la teinte de tous les autres widgets .. de manière à ne pas affecter les autres widgets tels que les cases à cocher et les boutons radio?
Bruce le
2
Mais cela modifie également la couleur d'autres contrôles, comme les boutons radio et la ligne sous modification du texte.
daka
66

Besoin d'ajouter un seul attribut à votre thème de barre d'outils -

<style name="toolbar_theme" parent="@style/ThemeOverlay.AppCompat.Dark.ActionBar">
    <item name="colorControlNormal">@color/arrow_color</item>
</style>

Appliquez ce toolbar_theme à votre barre d'outils.

OU

vous pouvez directement appliquer à votre thème -

<style name="CustomTheme" parent="Theme.AppCompat.Light.NoActionBar">
  <item name="colorControlNormal">@color/arrow_color</item> 
  //your code ....
</style>
Néo
la source
5
Essayer la réponse acceptée (peut-être la solution la plus populaire trouvée sur le net) ne fonctionne pas pour moi mais celle-ci fonctionne :) tellement fou lors de la programmation avec Android.
King King
4
Réponse la plus simple. Cela fonctionne sans changer les autres thèmes de contrôle. Tout ce dont vous avez besoin est de définir le thème de la barre d'outils personnalisée sur votre barre d'outils. :)
SimplyProgrammer
1
Oh les douleurs que vous devez traverser pour changer la couleur d'une seule icône .. La première fonctionne pour moi. Le 2ème fonctionne pour les barres d'outils personnalisées (et d'autres choses aussi apparemment). 3 ans plus tard, merci beaucoup Neo.
Aba
45

Il suffit d'ajouter

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

à votre thème d'application actuel.

S Bruce
la source
2
Cela change également la couleur android.support.v7.widget.AppCompatCheckBox
Udi Oshi
34

si vous l'utilisez Toolbar, vous pouvez essayer ceci

Drawable drawable = toolbar.getNavigationIcon();
drawable.setColorFilter(ContextCompat.getColor(appCompatActivity, colorId), PorterDuff.Mode.SRC_ATOP);
longbaobao
la source
Cela devrait être la réponse acceptée, à mon humble avis - elle ne cible que la flèche, obtient la flèche à définir en utilisant les moyens les plus simples et est également compatible en dessous de l'API 21
Antek
Si vous cherchez une solution plus personnalisée (différentes couleurs pour les titres et les icônes de menu dans mon cas), alors c'est la solution que vous voulez
TheJudge
3
Notez que vous devrez peut-être appeler ceci avant de tenter d'appeler getNavigationIcon (): getSupportActionBar (). SetDisplayHomeAsUpEnabled (true);
rrbrambley
La meilleure réponse! Je vous remercie.
islam shariful
32

Comme dit sur la plupart des commentaires précédents, la solution est d'ajouter

<item name="colorControlNormal">@color/white</item> au thème de votre application. Mais confirmez que vous n'avez pas d'autre thème défini dans votre élément Toolbar sur votre mise en page.

     <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" />
manuelvsc
la source
3
Génial ... J'ai essayé toutes les réponses à propos pour l'ajouter dans le thème mais cela n'a pas fonctionné ... Comme vous l'avez mentionné, j'avais la propriété android: theme = "@ style / ThemeOverlay.AppCompat.ActionBar" dans ma barre d'outils. Une fois que je l'ai supprimé, il a commencé à fonctionner.
Rahul Hawge
10

La réponse de Carles est la bonne réponse, mais peu de méthodes comme getDrawable (), getColor () sont devenues obsolètes au moment où j'écris cette réponse . La réponse mise à jour serait donc

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

Suite à d'autres requêtes stackoverflow, j'ai trouvé que l'appel de ContextCompat.getDrawable () est similaire à

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

Et ContextCompat.getColor () est similaire à

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

Lien 1: ContextCompat.getDrawable ()

Lien 2: ContextCompat.getColor ()

capt.swag
la source
Cela devrait être abc_ic_ab_back_material, au lieu de abc_ic_ab_back_mtrl_am_alpha.
Narendra Singh
7

J'ai trouvé une solution qui fonctionne avant Lollipop. Définissez le "colorControlNormal" dans le "actionBarWidgetTheme" pour changer la couleur homeAsUpIndicator. Modification de la réponse de rockgecko ci-dessus pour ressembler à ceci:

<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>
GFred
la source
7

Sur compileSdkVersoin 25, vous pouvez faire ceci:

styles.xml

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

Utilisez la méthode ci-dessous:

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

Vous pouvez maintenant définir le dessinable avec:

getSupportActionBar().setHomeAsUpIndicator(getColoredArrow());
Jumpa
la source
6

entrez la description de l'image ici

Changer la couleur de l'icône de navigation du menu

Couleur de l'icône du menu de conversion finale

Dans 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>
Sumit Saxena
la source
5

Une autre solution qui pourrait fonctionner pour vous est de ne pas déclarer votre barre d'outils comme barre d'action de l'application (par setActionBarou setSupportActionBar) et de définir l'icône de retour dans votre onActivityCreated en utilisant le code mentionné dans une autre réponse sur cette 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);

Désormais, vous ne recevrez pas le onOptionItemSelectedrappel lorsque vous appuyez sur le bouton de retour. Cependant, vous pouvez vous inscrire pour cela en utilisant setNavigationOnClickListener. C'est ce que je fais:

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

Je ne sais pas si cela fonctionnera si vous travaillez avec des éléments de menu.

Vinay W
la source
3

Nous étions confrontés au même problème et tout ce que nous voulions était de régler le

application: collapseIcon

attribut dans la barre d'outils à la fin, que nous n'avons pas trouvé car il n'est pas très bien documenté :)

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

essaye ça

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

appel de fonction:

enableActionBarHomeButton(this, R.color.white);
Siddarth Kanted
la source
La définition de l'option d'affichage {@link #DISPLAY_HOME_AS_UP} activera automatiquement le bouton d'accueil.
P. Savrov
2

C'est ce qui a fonctionné pour moi:

Ajoutez les attributs ci-dessous à votre thème.

Pour changer la flèche de retour de la barre d'outils / de la barre d'actions au-dessus de l'API 21

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

Pour changer la flèche de retour de la barre d'outils / de la barre d'action sous l'API 21

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

Pour changer la flèche arrière du mode d'action

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

Pour supprimer l'ombre de la barre d'outils / de la barre d'action

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

Pour modifier le dessin de dépassement de la barre d'actions

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

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

Remarque: 'srcCompat' est utilisé à la place de 'android: src' en raison de la prise en charge vectorielle dessiné pour les api inférieurs à 21

Sadashiv
la source
2

La solution est très simple

Mettez simplement la ligne suivante dans votre style nommé AppTheme

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

Maintenant, tout votre code xml ressemblera à celui ci-dessous (style par défaut).

<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>
Suyog
la source
1

Je viens de changer le thème de la barre d'outils pour être @ style / ThemeOverlay.AppCompat.Light

et la flèche est devenue gris foncé

            <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">
Badr
la source
1

Voici comment je l'ai fait dans 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>
Sam
la source
Mon pote, tu m'as sauvé la journée. J'ai passé toute la journée sur celui-ci seulement. J'aimerais pouvoir vous donner plus de votes.
Dhaval Patel le
0

Vous pouvez changer la couleur de l'icône de navigation par programme comme ceci:

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;
}
pks
la source
-1

Supprimez simplement android:homeAsUpIndicatoret homeAsUpIndicatorde votre thème et tout ira bien. L' colorattribut de votre DrawerArrowStylestyle doit être suffisant.

Flávio Faria
la source
J'ai déjà essayé ça et la flèche est noire. Notez que cette flèche n'est pas la même que celle que vous voyez lorsque vous ouvrez le tiroir (cette flèche EST affectée par l' colorattribut). La flèche du tiroir est un peu plus grande.
Ferran Maylinch
1
Donc, il semble que vous deviez fournir votre propre ressource dessinable. Vous pouvez le générer à l'aide de cet outil: shreyasachar.github.io/AndroidAssetStudio
Flávio Faria
-4

À moins qu'il n'y ait une meilleure solution ...

Ce que j'ai fait, c'est de prendre les @drawable/abc_ic_ab_back_mtrl_am_alphaimages, qui semblent blanches, et de les peindre dans la couleur que je désire à l'aide d'un éditeur de photos.

Ferran Maylinch
la source