studio item icon color change android menuitem textcolor layout-inflater

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



navigation view menu text color (23)

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

Por favor, avíseme si alguien tiene alguna solución para esto. La última opción será, obviamente, personalizarla, pero ¿hay alguna manera de cambiar el color del texto sin personalizarlo?


¡Lo encontré Eureka!

en el tema de su 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 del bar 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>

Saludos;)


Así es como puedes 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, perderá el efecto selector de fondo, por lo que aquí está el código para aplicar un selector de fondo personalizado a todos los elementos del menú secundarios.

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


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


El menú de opciones en Android se puede personalizar para configurar el fondo o cambiar la apariencia del texto. El fondo y el color del texto en el menú no se pudieron cambiar usando temas y estilos. El código fuente de Android (data / res / layout / icon_menu_item_layout.xml) usa un elemento personalizado de la clase "com.android.internal.view.menu.IconMenuItem" Ver 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 color de fondo y el 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); }


Gracias a max.musterman, esta es la solución que tengo para 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 Color.BLACK codificado podría convertirse en un parámetro adicional del método setMenuTextColor . Además, solo usé esto para elementos de menú que eran android:showAsAction="never" .


Gracias por el ejemplo de código. 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.


La forma más sencilla de crear un color de menú personalizado para una sola barra de herramientas, 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 personalizado de barra de herramientas

<style name="AppTheme.AppBarOverlay.MenuBlue"> <item name="actionMenuTextColor">@color/blue</item> </style>


La respuesta corta es sí. ¡eres afortunado!
Para hacerlo, debes sobrescribir 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 apariencia 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>

Entonces ahora tenemos el nombre del color en cuestión, si mira 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 debes hacer:

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


Lo hice programáticamente de esta manera:

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


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

Probado en API 16 con la biblioteca appcompat-v7-27.0.2 , AppCompatActivity para MainActivity y el tema AppCompat 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 textColorSecondary afecta 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 quise 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 explosionadas. Así que podría cambiar los estilos predeterminados y verificar los resultados. No sé cómo explotar las bibliotecas para usarlas directamente con Gradle o Android Studio . Merece otro hilo de investigación.

Así que 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 coloqué debajo de los predeterminados para anularlos y les #f00 valor #f00 a todos.
  2. Comience 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. Eliminando mis colores añadidos por bloques de 5-10 líneas, terminé con el elemento de color secondary_text_default_material_light .
  5. Buscando ese nombre en los archivos dentro de la carpeta res (o mejor dentro de res / colors ) encontré solo una ocurrencia en el archivo color / abc_secondary_text_material_light.xml (utilicé Sublime Text para estas operaciones, así que es más fácil encontrar lo que necesito).
  6. Volver al valor.xml Se encontraron 8 usos para @color/abc_secondary_text_material_light .
  7. Era un tema Light , por lo que quedan 4 en 2 temas: Base.ThemeOverlay.AppCompat.Light y Platform.AppCompat.Light .
  8. El primer tema era un elemento secundario del segundo, por lo que solo había 2 atributos con ese recurso de color: android:textColorSecondary y android:textColorTertiary en Base.ThemeOverlay.AppCompat.Light .
  9. Al cambiar sus valores directamente en values.xml y ejecutar la aplicación, encontré que el atributo correcto final era android:textColorSecondary .
  10. Luego necesité un tema u otro atributo para poder cambiarlo en style.xml de mi aplicación (porque mi tema tenía como principal el Theme.AppCompat.Light y no el ThemeOverlay.AppCompat.Light ).
  11. Busqué en el mismo archivo para Base.ThemeOverlay.AppCompat.Light . Tenía un niño ThemeOverlay.AppCompat.Light .
  12. Búsqueda de ThemeOverlay.AppCompat.Light Encontré su uso en el tema Base.Theme.AppCompat.Light.DarkActionBar como el valor del atributo actionBarPopupTheme .
  13. El tema de mi aplicación Theme.AppCompat.Light.DarkActionBar era un elemento secundario del Base.Theme.AppCompat.Light.DarkActionBar encontrado, así que podí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 del mencionado ThemeOverlay.AppCompat.Light y cambié el atributo android:textColorSecondary .


Para cambiar el color del texto, puede establecer una vista personalizada para MenuItem, y luego puede definir el color para el texto.

Código de muestra: MenuItem.setActionView ()


Parece que un

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

en mi tema y

<style name="myCustomMenuTextApearance" 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 los elementos del menú.


Puede cambiar fácilmente el color del texto de MenuItem utilizando SpannableString lugar 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); }


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


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

app:itemTextColor="your color"

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

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.


Si está utilizando la nueva Barra de herramientas, con el tema Theme.AppCompat.Light.NoActionBar , puede darle un estilo 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>`

De acuerdo con los resultados que obtuve,
android:textColorPrimary es el color del texto que muestra el nombre de su actividad, que es el texto principal de la barra de herramientas.

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

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

Finalmente, establezca 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"/>


Simplemente agrega esto a tu 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


Una simple línea en tu tema :)

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


Usé la etiqueta html para cambiar el color del texto de un 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; }


en Kotlin escribí estas extensiones:

fun MenuItem.setTitleColor(color: Int) { val hexColor = Integer.toHexString(color).toUpperCase().substring(2) val html = "<font color=''#" + hexColor + "''>" + this.title.toString() + "</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)


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


La solución de Sephy no funciona. Es posible anular la apariencia del texto del elemento de menú de opciones utilizando el método descrito anteriormente, pero no el elemento o 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. En general, esto lo digo porque generalmente puede hacer lo que quiera con estos métodos, pero probablemente no quiera llamar a super ().
  3. Copie el código del SDK de código abierto y personalícelo para su comportamiento. La implementación de menú predeterminada utilizada por Activity ya no se aplicará.

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


@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