Con la biblioteca de componentes de materiales puede utilizar estos atributos:
app:itemShapeFillColor
: color del elemento de fondo
app:itemIconTint
: tinte de icono
app:itemTextColor
: color de texto
En el diseño:
<com.google.android.material.navigation.NavigationView
app:itemShapeFillColor="@color/shape_selector"
app:itemIconTint="@color/icon_tint_selector"
app:itemTextColor="@color/text_color_selector"
../>
En un estilo personalizado:
<style name="..." parent="Widget.MaterialComponents.NavigationView" >
<item name="itemShapeFillColor">@color/shape_selector</item>
<item name="itemIconTint">@color/icon_tint_selector</item>
<item name="itemTextColor">@color/text_color_selector</item>
</style>
Para el itemIconTint
y itemTextColor
puedes usar un selector como este:
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:color="?attr/colorPrimary" android:state_checked="true"/>
<item android:alpha="0.38" android:color="?attr/colorOnSurface" android:state_enabled="false"/>
<item android:color="?attr/colorOnSurface"/>
</selector>
Para el itemShapeFillColor
puedes usar un selector como:
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:alpha="0.12" android:color="?attr/colorPrimary" android:state_activated="true"/>
<item android:alpha="0.12" android:color="?attr/colorPrimary" android:state_checked="true"/>
<item android:color="@android:color/transparent"/>
</selector>
Solo una nota final . Preste atención al uso de itemBackground
.
Está configurado para @null
usar un fondo con forma generado programáticamente por NavigationView
cuándo itemShapeAppearance
y / o itemShapeAppearanceOverlay
está configurado ( comportamiento predeterminado ).
Este fondo se diseña utilizando los itemShape*
atributos.
La configuración itemBackground
sobrescribirá el fondo programático y hará que los valores establecidos en los atributos itemShape * sean ignorados.
EditText
al menos si lo define en su Tema global.app:itemBackground="@drawable/my_ripple"
? Me sucede que cuando presiono un elemento, el que está en la parte inferior refleja el efecto dominó en lugar del que estoy presionando.NavigationDrawer (NavigationView) tiene tres opciones para la configuración de elementos marcados / seleccionados.
app:itemIconTint="@color/menu_text_color" //icon color app:itemTextColor="@color/menu_text_color" //text color app:itemBackground="@drawable/menu_background_color" //background
Color de icono y texto
Las dos primeras opciones (icono y texto) necesitan un recurso de lista de estado de color : https://developer.android.com/guide/topics/resources/color-list-resource.html .
Dicho
menu_text_color
recurso debe crearse en res / color . El contenido de este archivo debe tener un aspecto similar a:<!-- res/color/menu_text_color.xml --> <?xml version="1.0" encoding="utf-8"?> <selector xmlns:android="http://schemas.android.com/apk/res/android"> <item android:color="@color/colorWhite" android:state_checked="true" /> <item android:color="@color/colorBlack" android:state_checked="false"/> </selector>
@color/colorWhite
- recurso de color utilizado para el artículo marcado@color/colorBlack
- recurso de color utilizado para el elemento sin marcarHe creado un recurso para ambos, pero es posible crear dos archivos separados: uno para texto y otro para icono.
Fondo (itemBackground)
La opción de fondo necesita un recurso dibujable en lugar de color, cada intento de establecer el color terminará con una excepción. El recurso dibujable debe crearse en res / drawable y su contenido debe ser similar a:
<!-- res/drawable/menu_background_color.xml --> <?xml version="1.0" encoding="utf-8"?> <selector xmlns:android="http://schemas.android.com/apk/res/android"> <item android:drawable="@android:color/transparent" android:state_checked="false"/> <item android:drawable="@color/colorPrimary" android:state_checked="true"/> </selector>
No es necesario crear ningún elemento de diseño que simule el color (en otras soluciones vi tales propuestas, tal vez para la versión sdk anterior), el color se puede usar en este archivo directamente. En este archivo de ejemplo, estoy usando un color transparente para el elemento no marcado y
colorPrimary
para el elemento marcado.Solución de problemas y notas importantes
Ejemplo de código (agregar elemento de menú dinámico):
menu.add(group_id, item_id, Menu.NONE, item_name).setCheckable(true).setChecked(false);
Si los elementos no se configuran como comprobables, el fondo no funcionará (el color del texto y el icono sorprendente funcionarán como se esperaba).
fuente
remember to set items as checkable
. Gracias por mencionar esto, lo que nadie hizo.Usar colorControlHighlight es una buena solución para mí. Tenga en cuenta que con la biblioteca de soporte más reciente, puede definir un tema (no solo el estilo) para cada widget; por ejemplo, puede definir colorControlHighlight en el tema NavigationView y esto no se aplicará al resto de widgets.
fuente
<item name="android:colorControlHighlight">@color/navigationDrawerTextNight</item>
pero ¿cómo se aplica al texto del elemento del menú?itemTextColor
no existe en un estiloSi desea cambiar solo un color de elemento de menú de su actividad en función de los eventos, consulte este blog de HANIHASHEMI:
https://hanihashemi.com/2017/05/06/change-text-color-of-menuitem-in-navigation-drawer/
private void setTextColorForMenuItem(MenuItem menuItem, @ColorRes int color) { SpannableString spanString = new SpannableString(menuItem.getTitle().toString()); spanString.setSpan(new ForegroundColorSpan(ContextCompat.getColor(this, color)), 0, spanString.length(), 0); menuItem.setTitle(spanString); }
Método de llamada
setTextColorForMenuItem(item, R.color.colorPrimary);
Si trabaja con Xamarin Android, intente esto:
private void SetTextColorForMenuItem(IMenuItem menuItem, Android.Graphics.Color color) { SpannableString spanString = new SpannableString(menuItem.TitleFormatted.ToString()); spanString.SetSpan(new ForegroundColorSpan(color), 0, spanString.Length(), 0); menuItem.SetTitle(spanString); }
Método de llamada:
SetTextColorForMenuItem(navigationView.Menu.GetItem(0), Android.Graphics.Color.OrangeRed);
fuente
Puede usar programáticamente este código:
int[][] states = new int[][] { new int[] { android.R.attr.state_enabled}, // enabled new int[] {-android.R.attr.state_enabled}, // disabled new int[] {-android.R.attr.state_checked}, // unchecked new int[] { android.R.attr.state_pressed} // pressed }; int[] colors = new int[] { Color.BLACK, Color.RED, Color.GREEN, Color.BLUE }; ColorStateList myList = new ColorStateList(states, colors); nav_view.setItemIconTintList(myList);
fuente
Ahora, en la vista de navegación, también puede proporcionar su propia vista de elementos. Con lo nuevo
appcompat-v7:23.1.0
puedesView view = View.inflate(context, R.layout.your_custom_nav_layout_item, null); MenuItemCompat.setActionView(menuItem, view);
De esta manera, puede crear su propio diseño con TextView y cambiarlo
backgrounds/colors/fonts
como desee. Espero que esto haya sido útil :) Fuentefuente
Si desea hacer esto mediante programación:
Basado en la respuesta de Jhon:
Puede usar la extensión Kotlin de esta manera:
fun NavigationView.setTextColorForMenuItems(@ColorInt color: Int) { for (i: Int in 0 until menu.size()) { val menuItem = menu.getItem(i) val spanString = SpannableString(menuItem.title.toString()) spanString.setSpan(ForegroundColorSpan(color), 0, spanString.length, 0) menuItem.title = spanString } }
Luego llame
nav_view.setTextColorForMenuItems(Color.BLACK)
fuente
Puedes hacerlo usando la siguiente declaración:
navigationView.setItemBackground(ContextCompat.getDrawable(CustomerHomeActivity.this, R.color.transparent));
fuente