¿Cómo cambiar el color de la flecha hacia atrás en el nuevo tema de material?

193

He actualizado mi SDK a API 21 y ahora el ícono de retroceder / subir es una flecha negra que apunta a la izquierda.

Flecha negra hacia atrás

Me gustaría que fuera gris. ¿Cómo puedo hacer eso?

En Play Store, por ejemplo, la flecha es blanca.

He hecho esto para configurar algunos estilos. He usado @drawable/abc_ic_ab_back_mtrl_am_alphapara homeAsUpIndicator. Ese dibujo es transparente (solo alfa) pero la flecha se muestra en negro. Me pregunto si puedo configurar el color como lo hago en el DrawerArrowStyle. O si la única solución es crear mi @drawable/grey_arrowy usarlo para 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>

Mi solución hasta ahora ha sido tomar el @drawable/abc_ic_ab_back_mtrl_am_alpha, que parece ser blanco, y pintarlo del color que deseo usando un editor de fotos. Funciona, aunque preferiría usar @color/actionbar_textlike in DrawerArrowStyle.

Ferran Maylinch
fuente
Hasta ahora, ninguna de las respuestas basadas en XML me ha resuelto este problema, pero he utilizado con éxito su código homeAsUpIndicator/ @drawable/abc_ic_ab_back_mtrl_am_alphapara hacer que la flecha hacia atrás sea blanca. Prefiero esto que piratear Java.
prohibición de geoingeniería el
Viejo pero quieto. ¿Está (estaba) usando ActionBar o la nueva barra de herramientas?
f470071
Se supone que el predeterminado es un poco gris, usando android: theme = "@ style / Widget.AppCompat.Light.ActionBar" dentro de la etiqueta XML de la barra Google. Su color es # 737373
desarrollador de Android

Respuestas:

354

Puedes lograrlo a través del código. Obtenga la flecha de retroceso dibujable, modifique su color con un filtro y configúrelo como botón de retroceso.

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

Revisión 1:

A partir de API 23 (Marshmallow), el recurso extraíble abc_ic_ab_back_mtrl_am_alphase cambia a abc_ic_ab_back_material.

EDITAR:

Puede usar este código para lograr los resultados que desea:

toolbar.getNavigationIcon().setColorFilter(getResources().getColor(R.color.blue_gray_15), PorterDuff.Mode.SRC_ATOP);
Carles
fuente
44
Esto es lo único que funcionó para mí sin cambiar el tinte de todos los demás widgets con colorControlNormal
Joris
44
El problema con esta solución es que pinta todas las demás flechas hacia atrás, si solo desea cambiar una y dejar el resto en blanco
toque el
24
Funciona. Tenga en cuenta que debe usar ContextCompat.getDrawable(this, R.drawable.abc_ic_ab_back_mtrl_am_alpha)porque getResources.getDrawable(int)está en desuso
mrroboaat
3
Otra posible solución sería obtener ese recurso usted mismo y ponerlo en sus carpetas
dibujables
12
Tenga en cuenta que abc_ic_ab_back_mtrl_am_alpha cambió a abc_ic_ab_back_material en la biblioteca de soporte 23.2.0
Jon
206

Mirando la fuente Toolbary TintManager, drawable/abc_ic_ab_back_mtrl_am_alphaestá teñida con el valor del atributo de estilo colorControlNormal.

Intenté configurar esto en mi proyecto (con <item name="colorControlNormal">@color/my_awesome_color</item>mi tema), pero todavía es negro para mí.

Actualización :

Lo encontré. Debe establecer el actionBarThemeatributo ( no actionBarStyle ) con colorControlNormal.

P.ej:

<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
fuente
44
Esta debería ser la respuesta aceptada. Gracias por esto. Pregunta, no puedo encontrar el estilo para colorear la flecha que se muestra cuando se expande SearchView. ¿Cualquier pista? Aparentemente no se ve afectado por esta respuesta.
Daniel Ochoa
66
Tengo que añadir también <nombre del elemento = "android: colorControlNormal"> ... </ item> con el androide: prefijo
de Serafín
77
Desafortunadamente, esta es una API de nivel 21 y si desea admitir algo por debajo no funcionará.
gphilip
10
Si su tema principal se deriva de uno de los temas "NoActionBar", la ruta a seguir es establecer colorControlNormalel tema raíz en lugar de en el tema actionBarTheme.
Jason Robinson
3
Solo me tomó 2 horas de búsqueda y fallar y buscar nuevamente para finalmente llegar a esto. ¡A veces el estilo 'sistema' en Android me vuelve loco! Este método es especialmente importante cuando tiene una actividad que no usa el mismo estilo que las otras.
Bron Davies
119

Intenté todas las sugerencias anteriores. La única forma en que logré cambiar el color de la flecha predeterminada del botón Atrás del icono de navegación en mi barra de herramientas es establecer colorControlNormal en el tema base como este. Probablemente debido al hecho de que el padre está usando 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
fuente
66
La respuesta más simple de todas, en lugar de jugar con otro código, simplemente agregue esta línea en sustyle.xml
Rohan Kandwal
3
recuerde que colorControlNormal requiere API 21
Adnan Ali
3
@AdnanAli si está usando AppCompat, también funcionará en <API 21. Claramente, AppCompat está siendo utilizado aquí porque colorControlNormalestá no el prefijo android:.
Vicky Chijwani
3
Pero esto también cambia el tinte de todos los demás widgets ... ¿alguna forma de no afectar a otros widgets como la casilla de verificación y los botones de opción?
Bruce
2
Pero esto también cambia el color de otros controles, como los botones de opción y la línea debajo de la edición de texto.
daka
66

Necesita agregar un solo atributo al tema de su barra de herramientas:

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

Aplique este toolbar_theme a su barra de herramientas.

O

puedes aplicar directamente a tu tema -

<style name="CustomTheme" parent="Theme.AppCompat.Light.NoActionBar">
  <item name="colorControlNormal">@color/arrow_color</item> 
  //your code ....
</style>
Neo
fuente
55
Probar la respuesta aceptada (tal vez la solución más popular que se encuentra en la red) no funciona para mí, pero esta funciona :) muy loco cuando se programa con Android.
Rey Rey
44
La respuesta más simple. Esto funciona sin cambiar otros temas de control. Todo lo que necesita es establecer el tema de la barra de herramientas personalizada en su barra de herramientas. :)
SimplyProgrammer
1
Oh, los dolores que tienes que pasar para cambiar el color de solo 1 ícono. El primero funciona para mí. El segundo funciona para barras de herramientas personalizadas (y otras cosas aparentemente). 3 años después, muchas gracias Neo.
Aba
45

Solo agrega

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

a su tema de aplicación actual.

S bruce
fuente
2
Esto está cambiando el color android.support.v7.widget.AppCompatCheckBox también
Udi Oshi
34

si lo usa Toolbar, puede probar esto

Drawable drawable = toolbar.getNavigationIcon();
drawable.setColorFilter(ContextCompat.getColor(appCompatActivity, colorId), PorterDuff.Mode.SRC_ATOP);
longbaobao
fuente
Esta debería ser la respuesta aceptada, en mi opinión: apunta solo a la flecha, establece la flecha usando los medios más simples y es compatible también por debajo de API 21
Antek
Si busca una solución más personalizada (diferentes colores para títulos e íconos de menú en mi caso), entonces esta es la solución que desea
TheJudge
3
Tenga en cuenta que es posible que deba llamar a esto antes de intentar llamar a getNavigationIcon (): getSupportActionBar (). SetDisplayHomeAsUpEnabled (true);
rrbrambley
La mejor respuesta! Gracias.
Shariful Islam
32

Como se dijo en la mayoría de los comentarios anteriores, la solución es agregar

<item name="colorControlNormal">@color/white</item> al tema de tu aplicación. Pero confirme que no tiene otro tema definido en su elemento Barra de herramientas en su diseño.

     <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
fuente
3
Brillante ... Intenté todas las respuestas para agregarlo en el tema, pero no funcionó ... Como mencionaste, tenía la propiedad android: theme = "@ style / ThemeOverlay.AppCompat.ActionBar" en mi barra de herramientas. Una vez que lo quité, comenzó a funcionar.
Rahul Hawge
10

La respuesta de Carles es la respuesta correcta, pero pocos de los métodos como getDrawable (), getColor () quedaron en desuso en el momento en que escribo esta respuesta . Entonces la respuesta actualizada sería

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

Siguiendo algunas otras consultas de stackoverflow, descubrí que llamar a ContextCompat.getDrawable () es similar a

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

Y ContextCompat.getColor () es similar a

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

Enlace 1: ContextCompat.getDrawable ()

Enlace 2: ContextCompat.getColor ()

capt.swag
fuente
Debería ser abc_ic_ab_back_material, en lugar de abc_ic_ab_back_mtrl_am_alpha.
Narendra Singh
7

Encontré una solución que funciona antes de Lollipop. Establezca "colorControlNormal" dentro de "actionBarWidgetTheme" para cambiar el color de homeAsUpIndicator. Modificando la respuesta de rockgecko desde arriba para que se vea así:

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

En compileSdkVersoin 25, puede hacer esto:

styles.xml

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

Utilice el siguiente método:

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

Ahora puedes configurar el dibujable con:

getSupportActionBar().setHomeAsUpIndicator(getColoredArrow());
Jumpa
fuente
6

ingrese la descripción de la imagen aquí

Cambiar el color del icono de navegación del menú

Conversión final Color del icono del menú

En 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
fuente
5

Otra solución que podría funcionar para usted es no declarar su barra de herramientas como la barra de acción de la aplicación (por setActionBaro setSupportActionBar) y establecer el icono de atrás en su onActivityCreated usando el código mencionado en otra respuesta en esta página

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

Ahora, no recibirá la onOptionItemSelecteddevolución de llamada cuando presione el botón Atrás. Sin embargo, puedes registrarte para eso usando setNavigationOnClickListener. Esto es lo que hago:

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

No estoy seguro de si funcionará si trabajas con elementos de menú.

Vinay W
fuente
3

Nos encontramos con el mismo problema y todo lo que queríamos era establecer el

aplicación: collapseIcon

atributo en la barra de herramientas al final, que no encontramos ya que no está muy bien documentado :)

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

prueba esto

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

Llamada de función:

enableActionBarHomeButton(this, R.color.white);
Siddarth Kanted
fuente
Al configurar la opción de visualización {@link #DISPLAY_HOME_AS_UP}, se activará automáticamente el botón de inicio.
P. Savrov
2

Esto es lo que funcionó para mí:

Agregue los siguientes atributos a su tema.

Para cambiar la barra de herramientas / barra de acción flecha hacia atrás arriba de la API 21

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

Para cambiar la barra de herramientas / barra de acción flecha hacia atrás debajo de la API 21

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

Para cambiar el modo de acción flecha hacia atrás

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

Para eliminar la barra de herramientas / barra de acciones sombra

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

Para cambiar el desbordamiento de la barra de acción dibujable

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

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

Nota: 'srcCompat' se usa en lugar de 'android: src' debido a la compatibilidad de dibujo vectorial para la API por debajo de 21

Sadashiv
fuente
2

La solución es muy simple.

Simplemente ponga la siguiente línea en su estilo llamado AppTheme

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

Ahora todo su código xml se verá como se muestra a continuación (estilo predeterminado).

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

Acabo de cambiar el tema de la barra de herramientas para que sea @ style / ThemeOverlay.AppCompat.Light

y la flecha se volvió gris oscuro

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

Así es como lo hice en Componentes de material:

<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
fuente
Amigo, me salvaste el día. Pasé todo el día solo en este. Desearía poder darte más votos.
Dhaval Patel
0

Puede cambiar el color del icono de navegación mediante programación de esta manera:

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

Simplemente elimine android:homeAsUpIndicatory homeAsUpIndicatorde su tema y estará bien. El coloratributo en tu DrawerArrowStyleestilo debe ser suficiente.

Flávio Faria
fuente
Ya lo intenté y la flecha es negra. Tenga en cuenta que esta flecha no es la misma flecha que ve cuando abre el cajón (esa flecha ES afectada por el coloratributo). La flecha del cajón es un poco más grande.
Ferran Maylinch
1
Entonces, parece que tendrá que proporcionar su propio recurso dibujable. Puede generarlo usando esta herramienta: shreyasachar.github.io/AndroidAssetStudio
Flávio Faria
-4

A menos que haya una mejor solución ...

Lo que hice fue tomar las @drawable/abc_ic_ab_back_mtrl_am_alphaimágenes, que parecen ser blancas, y pintarlas en el color que deseo usando un editor de fotos.

Ferran Maylinch
fuente