¿Cómo cambiar el color del texto del elemento del menú en Android?

175

¿Puedo cambiar el color de fondo de un elemento de menú en Android?

Avíseme si alguien tiene alguna solución para esto. Obviamente, la última opción será personalizarlo, pero hay alguna forma de cambiar el color del texto sin personalizarlo.

sunil
fuente
¿Hay alguien que pueda hacerme saber la solución a esto?
sunil
3
¿Desea cambiar el color del texto, el color de fondo de la vista de texto? ¿o ambos? Ambas son cosas diferentes. Por favor, vuelva a enmarcar la pregunta.
Abhinav Saxena

Respuestas:

335

Una línea simple en tu tema :)

<item name="android:actionMenuTextColor">@color/your_color</item>
Muhammad Alfaifi
fuente
19
NOTA: Esto DEBE ir en la definición del tema principal para su aplicación, NO dentro del actionBarStylepor ejemplo. No funcionará dentro actionBarStyle, ¡aunque parezca lógico!
Colin M.
47
Para admitir versiones de API inferiores <item name="actionMenuTextColor">@color/your_color</item>, no use el espacio de nombres de Android
alex.p
55
@ColinM. Tiene que entrar en un tema. Si establece un themeatributo en su barra de herramientas, esto funciona.
DariusL
2
No funcionaba para mí con o sin Android: espacio de nombres. Fue agregado al tema principal de la aplicación.
racs
2
Todavía soy completamente incapaz de cambiar el color del texto. Mi color de texto de tema general solo tiene preferencia. ¿Alguna ayuda? Ninguna de estas respuestas funciona.
David P
114

Parece que un

  <item name="android:itemTextAppearance">@style/myCustomMenuTextAppearance</item>

en mi tema y

   <style name="myCustomMenuTextAppearance" parent="@android:style/TextAppearance.Widget.IconMenu.Item">
        <item name="android:textColor">@android:color/primary_text_dark</item>
    </style>

en styles.xml cambia el estilo de los elementos de la lista pero no de los elementos del menú.

Marcus Wolschon
fuente
55
Esto funciona muy bien para los elementos del menú contextual (no los elementos del menú desde el botón de menú) que es lo que he estado buscando. Mucho más simple que todo el desorden de LayoutFactory.
chubbsondubs
El android:itemTextAppearanceatributo no se puede colocar dentro de un estilo cuyo padre es, parent="@android:style/Widget.Holo.ListPopupWindow"ya que no se representará correctamente. Debe estar en un estilo de nivel superior como uno cuyo padre es android:Theme.Holo.Light.DarkActionBar.
toobsco42
¿Dónde debo agregar <item name = "android: itemTextAppearance"> @ style / myCustomMenuTextApearance </item>?
Bagusflyer
@bagusflyer se debe añadir que en el estilo de raíz de su tema, es decir, el estilo que es un hijo de Theme.Holoo Theme.Holo.Light.DarkActionBaro similar.
Tash Pemhiwa
86

Puede cambiar el color del MenuItemtexto fácilmente usando en SpannableStringlugar de String.

@Override
public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
    inflater.inflate(R.menu.your_menu, menu);

    int positionOfMenuItem = 0; // or whatever...
    MenuItem item = menu.getItem(positionOfMenuItem);
    SpannableString s = new SpannableString("My red MenuItem");
    s.setSpan(new ForegroundColorSpan(Color.RED), 0, s.length(), 0);
    item.setTitle(s);
}
max.mustermann
fuente
10
Esto funcionó para mí en 4.4 y 5+ usando en menu.findItem(R.id.menu_item_id);lugar demenu.getItem()
haagmm
1
También funcionó para mí [usando findItem (...)].
aturdido el
66
las soluciones funcionan solo para el elemento en desbordamiento ... no quiero cambiar el color del elemento que es visible estableciendo showAsAction: "always"
Junaid
56

Si está utilizando la nueva barra de herramientas, con el tema Theme.AppCompat.Light.NoActionBar, puede diseñarla de la siguiente manera.

 <style name="ToolbarTheme" parent="Theme.AppCompat.Light.NoActionBar">
    <item name="android:textColorPrimary">@color/my_color1</item>
    <item name="android:textColorSecondary">@color/my_color2</item>
    <item name="android:textColor">@color/my_color3</item>
 </style>`

Según los resultados que obtuve,
android:textColorPrimaryes el color del texto que muestra el nombre de su actividad, que es el texto principal de la barra de herramientas.

android:textColorSecondaryes el color del texto para el botón de subtítulos y más opciones (3 puntos). (Sí, ¡cambió su color de acuerdo con esta propiedad!)

android:textColorEs el color de todos los demás textos, incluido el menú.

Finalmente establece el tema en la barra de herramientas

<android.support.v7.widget.Toolbar xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    app:theme="@style/ToolbarTheme"
    android:layout_height="wrap_content"
    android:layout_width="match_parent"
    android:minHeight="?attr/actionBarSize"/>
Sudara
fuente
¿Qué elemento gobierna el texto en los botones que se muestran como acciones (texto) en la barra de herramientas? Ni android: textColorPrimary, android: textColorSecondary ni android: textColor parecen afectarlos.
LarsH
En respuesta a mi pregunta en el comentario anterior: android:actionMenuTextColor(consulte stackoverflow.com/a/5538709/423105 ).
LarsH
32

Si está utilizando el menú como <android.support.design.widget.NavigationView />entonces, simplemente agregue la siguiente línea en NavigationView:

app:itemTextColor="your color"

También disponible en colorTint para ícono, también anulará el color de su ícono. Para eso tienes que agregar la siguiente línea:

app:itemIconTint="your color"

Ejemplo:

<android.support.design.widget.NavigationView
        android:id="@+id/nav_view"
        android:layout_width="wrap_content"
        android:layout_height="match_parent"
        android:layout_gravity="start"

        app:itemTextColor="@color/color_white"
        app:itemIconTint="@color/color_white"

        android:background="@color/colorPrimary"
        android:fitsSystemWindows="true"
        app:headerLayout="@layout/nav_header_main"
        app:menu="@menu/activity_main_drawer"/>

Espero que te ayude.

Mihir Trivedi
fuente
Esto cambió los elementos que están anidados en otro elemento, pero no cambió el elemento que contiene otros elementos. ¿Sabes cómo podría cambiarlos también?
Dinu Nicolae
@DinuNicolae ¿Puedes publicar tu captura de pantalla de ejemplo? O proporcione más detalles.
Mihir Trivedi
Tenía <item> <menu> <elementos internos> </menu> </item> y solo cambió el color de los elementos internos
Dinu Nicolae
31

Lo hice programáticamente así:

public boolean onCreateOptionsMenu(Menu menu) {
    getMenuInflater().inflate(R.menu.changeip_card_menu, menu); 
    for(int i = 0; i < menu.size(); i++) {
        MenuItem item = menu.getItem(i);
        SpannableString spanString = new SpannableString(menu.getItem(i).getTitle().toString());
        spanString.setSpan(new ForegroundColorSpan(Color.BLACK), 0,     spanString.length(), 0); //fix the color to white
        item.setTitle(spanString);
    }
    return true;
}
Muralikrishna GS
fuente
2
su respuesta me ayudó a establecer el texto de MenuItem en negrita. (s.setSpan (nuevo StyleSpan (android.graphics.Typeface.BOLD), 0, s.length (), 0); ¡Gracias!
Arkadiusz Cieśliński
Esta solución ayudó a mi problema. Me gusta esto ya que no dependerá de las condiciones relacionadas con el tema.
Tomcat
15

como puede ver en esta pregunta , debe:

<item name="android:textColorPrimary">yourColor</item>

El código anterior cambia el color del texto de los elementos de acción del menú para API> = v21.

<item name="actionMenuTextColor">@android:color/holo_green_light</item>

Arriba está el código para API <v21

Pouya Danesh
fuente
Gracias. Esto debe ser aceptado. Es simple y fácil
Pooja
10

Usé la etiqueta html para cambiar el color del texto de un solo elemento cuando el elemento del menú está inflado. Espero que sea útil.

public boolean onCreateOptionsMenu(Menu menu) {
    // Inflate the menu; this adds items to the action bar if it is present.
    getMenuInflater().inflate(R.menu.menu_main, menu);
    menu.findItem(R.id.main_settings).setTitle(Html.fromHtml("<font color='#ff3824'>Settings</font>"));
    return true;
}
alijandro
fuente
1
Esto no funciona para mí en Marshmallow. Se aplica el texto, pero no el color.
Ollie C
Con respecto a Marshmallow, probablemente no funcione por la misma razón establecida en la respuesta de max.mustermann, "las soluciones funcionan solo para el elemento en desbordamiento".
Jose_GD
10

La forma MÁS SENCILLA de hacer un color de menú personalizado para una barra de herramientas única, no para AppTheme

    <android.support.design.widget.AppBarLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:theme="@style/AppTheme.AppBarOverlay.MenuBlue">
        <android.support.v7.widget.Toolbar
            android:id="@+id/toolbar"
            android:layout_width="match_parent"
            android:layout_height="?attr/actionBarSize"/>
    </android.support.design.widget.AppBarLayout>

barra de herramientas habitual en styles.xml

<style name="AppTheme.AppBarOverlay" parent="ThemeOverlay.AppCompat.Dark.ActionBar"/>

nuestro estilo de barra de herramientas personalizada

<style name="AppTheme.AppBarOverlay.MenuBlue">
    <item name="actionMenuTextColor">@color/blue</item>
</style>
AndrewS
fuente
¡Funciona genial! La mejor respuesta.
bebe
9

en Kotlin escribí estas extensiones:

fun MenuItem.setTitleColor(color: Int) {
    val hexColor = Integer.toHexString(color).toUpperCase().substring(2)
    val html = "<font color='#$hexColor'>$title</font>"
    this.title = html.parseAsHtml()
}           



@Suppress("DEPRECATION")                                                                        
fun String.parseAsHtml(): Spanned {                                                             
    return if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {                                
        Html.fromHtml(this, Html.FROM_HTML_MODE_LEGACY)                                         
    } else {                                                                                    
        Html.fromHtml(this)                                                                     
    }                                                                                           
}  

y usado así:

menu.findItem(R.id.main_settings).setTitleColor(Color.RED)
Amir Khorsandi
fuente
Realmente me gusta esta solución, muy ordenada!
Jamil Nawaz
Gracias, solución simple y rápida. Para API> 24 funciona sin esa segunda función ext
laszlo
7

La respuesta corta es sí. ¡eres afortunado!
Para hacerlo, debe anular algunos estilos de los estilos predeterminados de Android:

Primero, mira la definición de los temas en Android:

<style name="Theme.IconMenu">
<!-- Menu/item attributes -->
<item name="android:itemTextAppearance">@android:style/TextAppearance.Widget.IconMenu.Item</item>
<item name="android:itemBackground">@android:drawable/menu_selector</item>
<item name="android:itemIconDisabledAlpha">?android:attr/disabledAlpha</item>
<item name="android:horizontalDivider">@android:drawable/divider_horizontal_bright</item>
<item name="android:verticalDivider">@android:drawable/divider_vertical_bright</item>
<item name="android:windowAnimationStyle">@android:style/Animation.OptionsPanel</item>
<item name="android:moreIcon">@android:drawable/ic_menu_more</item>
<item name="android:background">@null</item>
</style>

Entonces, la aparición del texto en el menú está en @android:style/TextAppearance.Widget.IconMenu.Item
Ahora, en la definición de los estilos :

<style name="TextAppearance.Widget.IconMenu.Item" parent="TextAppearance.Small">
<item name="android:textColor">?textColorPrimaryInverse</item>
</style>

Así que ahora tenemos el nombre del color en cuestión, si busca en la carpeta de colores de los recursos del sistema:

<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:state_enabled="false" android:color="@android:color/bright_foreground_light_disabled" /> 
<item android:state_window_focused="false" android:color="@android:color/bright_foreground_light" /> 
<item android:state_pressed="true" android:color="@android:color/bright_foreground_light" /> 
<item android:state_selected="true" android:color="@android:color/bright_foreground_light" /> 
<item android:color="@android:color/bright_foreground_light" /> 
<!--  not selected --> 
</selector>

Finalmente, esto es lo que debe hacer:

Anule "TextAppearance.Widget.IconMenu.Item" y cree su propio estilo. Luego, vincúlelo a su propio selector para hacerlo de la manera que desee. Espero que esto te ayude. ¡Buena suerte!

Sephy
fuente
Gracias por responder. He hecho lo que usted sugiere, pero no cambiar el color del elemento de menú
Sunil
En realidad, me di cuenta al leer más cosas del menú que es mucho más complicado de lo que pensaba. Si no quieres crear tu propio menú personalizado completo ... Esto necesitará más lectura para mí, seguiré publicaste aquí si encuentro más.
Sephy
No es posible anular "TextAppearance.Widget.IconMenu.Item".
acepta el
Esta respuesta es engañosa ... así que la conclusión es que no funciona y es mucho más difícil / largo de alcanzar de lo que se pensaba originalmente.
speedynomads
6

El menú de opciones en Android se puede personalizar para establecer el fondo o cambiar la apariencia del texto. El fondo y el color del texto en el menú no se pueden cambiar usando temas y estilos. El código fuente de Android (data \ res \ layout \ icon_menu_item_layout.xml) utiliza un elemento personalizado de la clase "com.android.internal.view.menu.IconMenuItem" View para el diseño del menú. Podemos hacer cambios en la clase anterior para personalizar el menú. Para lograr lo mismo, use la clase de fábrica LayoutInflater y establezca el fondo y el color del texto para la vista.


@Override
public boolean onCreateOptionsMenu(Menu menu) {
    MenuInflater inflater = getMenuInflater();
    inflater.inflate(R.menu.my_menu, menu);
    getLayoutInflater().setFactory(new Factory() {
        @Override
        public View onCreateView(String name, Context context, AttributeSet attrs) {
            if (name .equalsIgnoreCase(“com.android.internal.view.menu.IconMenuItemView”)) {
                try{
                    LayoutInflater f = getLayoutInflater();
                    final View view = f.createView(name, null, attrs);
                    new Handler().post(new Runnable() {
                        public void run() {
                            // set the background drawable
                            view .setBackgroundResource(R.drawable.my_ac_menu_background);

                            // set the text color
                            ((TextView) view).setTextColor(Color.WHITE);
                        }
                    });
                    return view;
                } catch (InflateException e) {
                    } catch (ClassNotFoundException e) {}
            }
            return null;
        }
    });
    return super.onCreateOptionsMenu(menu);
}


Abhay Kumar
fuente
3
03-23 19:45:25.134: E/AndroidRuntime(26761): java.lang.IllegalStateException: A factory has already been set on this LayoutInflater
A Kra
Esto funciona por primera vez. Cuando abres el menú por segunda vez, obtienes una excepción.
LoveForDroid
6

Gracias por el código de ejemplo. Tuve que modificarlo para que funcione con un menú contextual. Esta es mi solución

    static final Class<?>[] constructorSignature = new Class[] {Context.class, AttributeSet.class};

class MenuColorFix implements LayoutInflater.Factory {
    public View onCreateView(String name, Context context, AttributeSet attrs) {
        if (name.equalsIgnoreCase("com.android.internal.view.menu.ListMenuItemView")) {
            try {
                Class<? extends ViewGroup> clazz = context.getClassLoader().loadClass(name).asSubclass(ViewGroup.class);
                Constructor<? extends ViewGroup> constructor = clazz.getConstructor(constructorSignature);
                final ViewGroup view = constructor.newInstance(new Object[]{context,attrs});

                new Handler().post(new Runnable() {
                    public void run() {
                        try {
                            view.setBackgroundColor(Color.BLACK);
                            List<View> children = getAllChildren(view);
                            for(int i = 0; i< children.size(); i++) {
                                View child = children.get(i);
                                if ( child instanceof TextView ) {
                                    ((TextView)child).setTextColor(Color.WHITE);
                                }
                            }
                        }
                        catch (Exception e) {
                            Log.i(TAG, "Caught Exception!",e);
                        }

                    }
                });
                return view;
            }
            catch (Exception e) {
                Log.i(TAG, "Caught Exception!",e);
            }
        }
        return null;
    }       
}

public List<View> getAllChildren(ViewGroup vg) {
    ArrayList<View> result = new ArrayList<View>();
    for ( int i = 0; i < vg.getChildCount(); i++ ) {
        View child = vg.getChildAt(i);
        if ( child instanceof ViewGroup) {
            result.addAll(getAllChildren((ViewGroup)child));
        }
        else {
            result.add(child);
        }
    }
    return result;
}

@Override
public void onCreateContextMenu(ContextMenu menu, View v, ContextMenuInfo menuInfo) {
    LayoutInflater lInflater = getLayoutInflater();
    if ( lInflater.getFactory() == null ) {
        lInflater.setFactory(new MenuColorFix());
    }
    super.onCreateContextMenu(menu, v, menuInfo);
    MenuInflater inflater = getMenuInflater();
    inflater.inflate(R.menu.myMenu, menu);
}

Para mí esto funciona con Android 1.6, 2.03 y 4.03.

Michael Vogl
fuente
Si está haciendo lo anterior, entonces debería considerar usar la solución de Marcus Wolschon. Mucho más simple
chubbsondubs
La solución xml no funciona para mí, por ejemplo, en 2.3.x, pero funciona de maravilla, también en 4.x
sunlock
Esta solución funcionó mejor. También tuve que capturar android.support.v7.internal.view.menu.ListMenuItemView para aplicar los estilos en dispositivos que usan la biblioteca de compatibilidad
Chiatar
Esta solución no funcionará con Google Maps v2: el súper método debe llamarse primero para que los mapas se representen correctamente.
Chiatar
5

Lo encontré Eureka !!

en el tema de tu aplicación:

<style name="AppTheme" parent="Theme.AppCompat.Light.DarkActionBar">
    <item name="android:actionBarStyle">@style/ActionBarTheme</item>
    <!-- backward compatibility -->          
    <item name="actionBarStyle">@style/ActionBarTheme</item>        
</style>

Aquí está el tema de su barra de acción:

<style name="ActionBarTheme" parent="@style/Widget.AppCompat.Light.ActionBar.Solid.Inverse">
   <item name="android:background">@color/actionbar_bg_color</item>
   <item name="popupTheme">@style/ActionBarPopupTheme</item
   <!-- backward compatibility -->
   <item name="background">@color/actionbar_bg_color</item>
</style>

y aquí está tu tema emergente:

 <style name="ActionBarPopupTheme">
    <item name="android:textColor">@color/menu_text_color</item>
    <item name="android:background">@color/menu_bg_color</item>
 </style>

Salud ;)

Alnamrouti Fareed
fuente
5

para cambiar el color del texto del elemento del menú, use el siguiente código

<style name="AppToolbar" parent="Theme.AppCompat.Light.NoActionBar">
<item name="android:itemTextAppearance">@style/menu_item_color</item>
</style>

dónde

<style name="menu_item_color">
<item name="android:textColor">@color/app_font_color</item>
</style>
Muhammad Abdullah
fuente
4

Gracias a max.musterman, esta es la solución que llegué a trabajar en el nivel 22:

public boolean onCreateOptionsMenu(Menu menu) {
    getMenuInflater().inflate(R.menu.menu_main, menu);
    SearchManager searchManager = (SearchManager) getSystemService(Context.SEARCH_SERVICE);
    MenuItem searchMenuItem = menu.findItem(R.id.search);
    SearchView searchView = (SearchView) searchMenuItem.getActionView();
    searchView.setSearchableInfo(searchManager.getSearchableInfo(getComponentName()));
    searchView.setSubmitButtonEnabled(true);
    searchView.setOnQueryTextListener(this);
    setMenuTextColor(menu, R.id.displaySummary, R.string.show_summary);
    setMenuTextColor(menu, R.id.about, R.string.text_about);
    setMenuTextColor(menu, R.id.importExport, R.string.import_export);
    setMenuTextColor(menu, R.id.preferences, R.string.settings);
    return true;
}

private void setMenuTextColor(Menu menu, int menuResource, int menuTextResource) {
    MenuItem item = menu.findItem(menuResource);
    SpannableString s = new SpannableString(getString(menuTextResource));
    s.setSpan(new ForegroundColorSpan(Color.BLACK), 0, s.length(), 0);
    item.setTitle(s);
}

El hardcoded Color.BLACKpodría convertirse en un parámetro adicional para el setMenuTextColormétodo. Además, solo usé esto para elementos de menú que eran android:showAsAction="never".

encargado de la luz
fuente
No funciona para mí en API 24. ¿Alguna idea? Estuve atrapado en esto durante días ... ¡ridículo!
David P
No estoy seguro que decirte. Esto funciona bien para mí en API 25.
lightkeeper
3

Puede configurar el color mediante programación.

private static void setMenuTextColor(final Context context, final Toolbar toolbar, final int menuResId, final int colorRes) {
    toolbar.post(new Runnable() {
        @Override
        public void run() {
            View settingsMenuItem =  toolbar.findViewById(menuResId);
            if (settingsMenuItem instanceof TextView) {
                if (DEBUG) {
                    Log.i(TAG, "setMenuTextColor textview");
                }
                TextView tv = (TextView) settingsMenuItem;
                tv.setTextColor(ContextCompat.getColor(context, colorRes));
            } else { // you can ignore this branch, because usually there is not the situation
                Menu menu = toolbar.getMenu();
                MenuItem item = menu.findItem(menuResId);
                SpannableString s = new SpannableString(item.getTitle());
                s.setSpan(new ForegroundColorSpan(ContextCompat.getColor(context, colorRes)), 0, s.length(), 0);
                item.setTitle(s);
            }

        }
    });
}
Victor Choy
fuente
3

Agregar esto a mi styles.xml funcionó para mí

<item name="android:textColorPrimary">?android:attr/textColorPrimaryInverse</item>
Asim
fuente
2

Simplemente agregue esto a su tema

<style name="AppTheme" parent="Theme.AppCompat.Light.NoActionBar">
        <item name="android:itemTextAppearance">@style/AppTheme.ItemTextStyle</item>
</style>

<style name="AppTheme.ItemTextStyle" parent="@android:style/TextAppearance.Widget.IconMenu.Item">
        <item name="android:textColor">@color/orange_500</item>
</style>

Probado en API 21

Pham Quan
fuente
2
Es mejor usarlo <style name="AppTheme.ItemTextStyle" parent="@android:style/TextAppearance.Widget">, de lo contrario el texto parece demasiado pequeño en el menú de desbordamiento. También tenga en cuenta que esta técnica solo funciona en Android 5 y superior.
Mr-IDE el
2
@Override
public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
    inflater.inflate(R.menu.search, menu);


    MenuItem myActionMenuItem = menu.findItem( R.id.action_search);
    SearchView searchView = (SearchView) myActionMenuItem.getActionView();

    EditText searchEditText = (EditText) searchView.findViewById(android.support.v7.appcompat.R.id.search_src_text);
    searchEditText.setTextColor(Color.WHITE); //You color here
Bäda
fuente
1
explique su respuesta
Codificador
1
¿Qué pasa si no es un SearchView?
nasch
2

Mi situación fue la configuración del color del texto en el menú de opciones (el menú principal de la aplicación se mostró al presionar el botón de menú).

Probado de API 16 con appcompat-v7-27.0.2 biblioteca, AppCompatActivitypara MainActivityy AppCompattema para la aplicación en AndroidManifest.xml .

styles.xml :

<style name="AppTheme" parent="Theme.AppCompat.Light.DarkActionBar">
  <item name="actionBarPopupTheme">@style/PopupTheme</item>
</style>

<style name="PopupTheme" parent="@style/ThemeOverlay.AppCompat.Light">
  <item name="android:textColorSecondary">#f00</item>
</style>

No sé si eso textColorSecondaryafecta a otros elementos pero controla el color del texto del menú.


Busqué algunos ejemplos sobre el tema, pero todos los fragmentos listos para usar no funcionaron.

Así que quería investigarlo con el código fuente de la biblioteca appcompat-v7 (específicamente con la carpeta res del paquete .aar ).

Aunque en mi caso usé Eclipse con dependencias .aar explotadas . Entonces podría cambiar los estilos predeterminados y verificar los resultados. No sé cómo explotar las bibliotecas para usar con Gradle o Android Studio directamente. Se merece otro hilo de investigación.

Entonces, mi propósito era encontrar qué color en el archivo res / values ​​/ values.xml se usa para el texto del menú (estaba casi seguro de que el color estaba allí).

  1. Abrí ese archivo, luego dupliqué todos los colores, los puse debajo de los predeterminados para anularlos y asigné #f00 valor.
  2. Inicia la aplicación.
  3. Muchos elementos tenían fondo rojo o color de texto. Y los elementos del menú también. Eso era lo que necesitaba.
  4. Al eliminar mis colores agregados por bloques de 5-10 líneas, terminé con el secondary_text_default_material_lightelemento de color.
  5. Al buscar ese nombre en los archivos dentro de la carpeta res (o mejor dentro de res / colors ) encontré solo una aparición en color / abc_secondary_text_material_light.xml archivo (utilicé Sublime Text para estas operaciones, por lo que es más fácil encontrar lo que necesito).
  6. Volviendo a los valores.xml se encontraron 8 usos para@color/abc_secondary_text_material_light .
  7. Era un tema ligero , así que quedaban 4 en 2 temas: Base.ThemeOverlay.AppCompat.LightyPlatform.AppCompat.Light .
  8. El primer tema fue hijo del segundo, por lo que solo había 2 atributos con ese recurso de color: android:textColorSecondaryy android:textColorTertiaryen el Base.ThemeOverlay.AppCompat.Light.
  9. Cambiando sus valores directamente en values.xml y ejecutando la aplicación, descubrí que el atributo correcto final era android:textColorSecondary.
  10. Luego necesitaba un tema u otro atributo para poder cambiarlo en el style.xml de mi aplicación (porque mi tema tenía como padre el Theme.AppCompat.Lighty no el ThemeOverlay.AppCompat.Light).
  11. Busqué en el mismo archivo el Base.ThemeOverlay.AppCompat.Light. Tuvo un hijo ThemeOverlay.AppCompat.Light.
  12. Al buscar ThemeOverlay.AppCompat.Light, encontré su uso en el Base.Theme.AppCompat.Light.DarkActionBartema como actionBarPopupThemevalor de atributo.
  13. El tema de mi aplicación Theme.AppCompat.Light.DarkActionBarera hijo de lo encontrado, Base.Theme.AppCompat.Light.DarkActionBarpor lo que podría usar ese atributo en mi styles.xml sin problemas.
  14. Como se ve en el código de ejemplo anterior, creé un tema secundario a partir de lo mencionado ThemeOverlay.AppCompat.Lighty cambié el android:textColorSecondaryatributo.

https://i.imgur.com/LNfKdzC.png

mortalis
fuente
1

La solución de Sephy no funciona. Es posible anular la apariencia del texto del elemento del menú de opciones utilizando el método descrito anteriormente, pero no el elemento o el menú. Para hacer eso hay esencialmente 3 formas:

  1. ¿Cómo cambiar el color de fondo del menú de opciones?
  2. Escriba su propia vista para mostrar y anular onCreateOptionsMenu y onPrepareOptionsMenu para obtener los resultados que desea. Lo digo generalmente porque generalmente puedes hacer lo que quieras con estos métodos, pero probablemente no quieras llamar a super ().
  3. Copie el código del SDK de código abierto y personalícelo según su comportamiento. La implementación de menú predeterminada utilizada por Activity ya no se aplicará.

Consulte el número 4441: Tema del menú de opciones personalizadas para obtener más pistas.

Tenaz
fuente
Para reiterar ... La solución de Sephy funciona para el elemento de menú TextAppearance, aunque lo que he hecho es anular el valor predeterminado a través de themes.xml. Además, # 2 o # 3 anteriores deben ser conscientes de que llamar a super # onCreateOptionsMenu / super # onPrepareOptionsMenu está diseñado para colocar elementos del menú del sistema ... como se indica en el javadoc para Activity # onCreateOptionsMenu (). Eso puede o no importar para su aplicación.
Tenaz
Lo que Sephy está describiendo es tener esto en su themes.xml: <item name = "android: itemTextAppearance"> @ style / Text_MenuItemText </item> Luego defina algo como esto en su styles.xml: <style name = "Text_MenuItemText" > <item name = "android: textSize"> 12dp </item> <item name = "android: textColor"> # FFFFFF </item> </style> Eso es lo más fácil posible. ¿A eso te referías? La personalización más profunda del menú de opciones no es fácil en absoluto, pero tengo la intención de publicar un artículo de blog al respecto pronto.
Tenaz el
1

prueba este código ...

 @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        MenuInflater inflater = getMenuInflater();
         inflater.inflate(R.menu.my_menu, menu);

        getLayoutInflater().setFactory(new Factory() {
            @Override
            public View onCreateView(String name, Context context,
                    AttributeSet attrs) {

                if (name.equalsIgnoreCase("com.android.internal.view.menu.IconMenuItemView")) {
                    try {
                        LayoutInflater f = getLayoutInflater();
                        final View view = f.createView(name, null, attrs);

                        new Handler().post(new Runnable() {
                            public void run() {

                                // set the background drawable
                                 view.setBackgroundResource(R.drawable.my_ac_menu_background);

                                // set the text color
                                ((TextView) view).setTextColor(Color.WHITE);
                            }
                        });
                        return view;
                    } catch (InflateException e) {
                    } catch (ClassNotFoundException e) {
                    }
                }
                return null;
            }
        });
        return super.onCreateOptionsMenu(menu);
    }
Anoop
fuente
1
en Android> 4.0 estoy llegandojava.lang.IllegalStateException: A factory has already been set on this LayoutInflater
A Kra
1

Si desea establecer el color para un elemento de menú individual, personalizar un tema de barra de herramientas no es la solución correcta. Para lograr esto, puede hacer uso de android: actionLayout y una vista de acción para el elemento del menú.

Primero cree un archivo de diseño XML para la vista de acción. En este ejemplo, usamos un botón como vista de acción:

menu_button.xml

<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <Button
        android:id="@+id/menuButton"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Done"
        android:textColor="?android:attr/colorAccent"
        style="?android:attr/buttonBarButtonStyle"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintTop_toTopOf="parent" />

</androidx.constraintlayout.widget.ConstraintLayout>

En el fragmento de código anterior, usamos android:textColor="?android:attr/colorAccent"para personalizar el color del texto del botón.

Luego, en su archivo de diseño XML para el menú, incluya lo app:actionLayout="@layout/menu_button"que se muestra a continuación:

main_menu.xml

<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto">

    <item
        android:id="@+id/menuItem"
        android:title=""
        app:actionLayout="@layout/menu_button"
        app:showAsAction="always"/>
</menu>

Última anulación del onCreateOptionsMenu()método en su actividad:

@Override
public boolean onCreateOptionsMenu(Menu menu) {
    getMenuInflater().inflate(R.menu.main_menu, menu);
    MenuItem item = menu.findItem(R.id.menuItem);
    Button saveButton = item.getActionView().findViewById(R.id.menuButton);
    saveButton.setOnClickListener(view -> {
        // Do something
    });
    return true;
}

... o fragmento:

@Override
public void onCreateOptionsMenu(@NonNull Menu menu, @NonNull MenuInflater inflater){
    inflater.inflate(R.menu.main_menu, menu);
    MenuItem item = menu.findItem(R.id.menuItem);
    Button saveButton = item.getActionView().findViewById(R.id.menuButton);
    button.setOnClickListener(view -> {
        // Do something
    });
}

Para obtener más detalles sobre las vistas de acción, consulte la guía para desarrolladores de Android .

Alexander Poleschuk
fuente
0

Así es como puede colorear un elemento de menú específico con color, funciona para todos los niveles de API:

public static void setToolbarMenuItemTextColor(final Toolbar toolbar,
                                               final @ColorRes int color,
                                               @IdRes final int resId) {
    if (toolbar != null) {
        for (int i = 0; i < toolbar.getChildCount(); i++) {
            final View view = toolbar.getChildAt(i);
            if (view instanceof ActionMenuView) {
                final ActionMenuView actionMenuView = (ActionMenuView) view;
                // view children are accessible only after layout-ing
                actionMenuView.post(new Runnable() {
                    @Override
                    public void run() {
                        for (int j = 0; j < actionMenuView.getChildCount(); j++) {
                            final View innerView = actionMenuView.getChildAt(j);
                            if (innerView instanceof ActionMenuItemView) {
                                final ActionMenuItemView itemView = (ActionMenuItemView) innerView;
                                if (resId == itemView.getId()) {
                                    itemView.setTextColor(ContextCompat.getColor(toolbar.getContext(), color));
                                }
                            }
                        }
                    }
                });
            }
        }
    }
}

Al hacerlo, pierde el efecto del selector de fondo, así que aquí está el código para aplicar un selector de fondo personalizado a todos los elementos secundarios del menú.

public static void setToolbarMenuItemsBackgroundSelector(final Context context,
                                                         final Toolbar toolbar) {
    if (toolbar != null) {
        for (int i = 0; i < toolbar.getChildCount(); i++) {
            final View view = toolbar.getChildAt(i);
            if (view instanceof ImageButton) {
                // left toolbar icon (navigation, hamburger, ...)
                UiHelper.setViewBackgroundSelector(context, view);
            } else if (view instanceof ActionMenuView) {
                final ActionMenuView actionMenuView = (ActionMenuView) view;

                // view children are accessible only after layout-ing
                actionMenuView.post(new Runnable() {
                    @Override
                    public void run() {
                        for (int j = 0; j < actionMenuView.getChildCount(); j++) {
                            final View innerView = actionMenuView.getChildAt(j);
                            if (innerView instanceof ActionMenuItemView) {
                                // text item views
                                final ActionMenuItemView itemView = (ActionMenuItemView) innerView;
                                UiHelper.setViewBackgroundSelector(context, itemView);

                                // icon item views
                                for (int k = 0; k < itemView.getCompoundDrawables().length; k++) {
                                    if (itemView.getCompoundDrawables()[k] != null) {
                                        UiHelper.setViewBackgroundSelector(context, itemView);
                                    }
                                }
                            }
                        }
                    }
                });
            }
        }
    }
}

Aquí está la función auxiliar también:

public static void setViewBackgroundSelector(@NonNull Context context, @NonNull View itemView) {
    int[] attrs = new int[]{R.attr.selectableItemBackgroundBorderless};
    TypedArray ta = context.obtainStyledAttributes(attrs);
    Drawable drawable = ta.getDrawable(0);
    ta.recycle();

    ViewCompat.setBackground(itemView, drawable);
}
caja
fuente
0

Para cambiar el color del texto, puede establecer una vista personalizada para el elemento de menú y luego puede definir el color del texto.

Código de muestra: MenuItem.setActionView ()

ocio
fuente
Si bien este fragmento de código puede resolver la pregunta, incluir una explicación realmente ayuda a mejorar la calidad de su publicación. Recuerde que está respondiendo la pregunta para los lectores en el futuro, y que esas personas podrían no conocer los motivos de su sugerencia de código.
Mischa