Cuando utilizo elementos de diseño de la AppCompat
biblioteca para los Toolbar
elementos de mi menú, el teñido funciona como se esperaba. Me gusta esto:
<item
android:id="@+id/action_clear"
android:icon="@drawable/abc_ic_clear_mtrl_alpha" <-- from AppCompat
android:title="@string/clear" />
Pero si utilizo mis propios dibujables o incluso copio los dibujables de la AppCompat
biblioteca a mi propio proyecto, no se teñirá en absoluto.
<item
android:id="@+id/action_clear"
android:icon="@drawable/abc_ic_clear_mtrl_alpha_copy" <-- copy from AppCompat
android:title="@string/clear" />
¿Hay alguna magia especial en el AppCompat
Toolbar
que solo tiñe los dibujables de esa biblioteca? ¿Alguna forma de hacer que esto funcione con mis propios diseños?
Ejecutando esto en un dispositivo API de nivel 19 con compileSdkVersion = 21
y targetSdkVersion = 21
, y también usando todo, desdeAppCompat
abc_ic_clear_mtrl_alpha_copy
es una copia exacta del abc_ic_clear_mtrl_alpha
png deAppCompat
Editar:
El tinte se basa en el valor que he establecido android:textColorPrimary
en mi tema.
Por ejemplo <item name="android:textColorPrimary">#00FF00</item>
, me daría un color de tinte verde.
Capturas de pantalla
El teñido funciona como se esperaba con dibujable de AppCompat
El tinte no funciona con dibujable copiado de AppCompat
Respuestas:
Porque si echas un vistazo al código fuente de TintManager en AppCompat, verás:
Lo que básicamente significa que tienen ResourceIds particulares en la lista blanca para ser teñidos.
Pero supongo que siempre puedes ver cómo tiñen esas imágenes y hacen lo mismo. Es tan fácil como configurar ColorFilter en un dibujable.
fuente
Después de la nueva biblioteca de soporte v22.1, puede usar algo similar a esto:
fuente
setColorFilter()
es preferible.Establecer un
ColorFilter
(tinte) en aMenuItem
es simple. Aquí hay un ejemplo:El código anterior es muy útil si desea admitir diferentes temas y no desea tener copias adicionales solo por el color o la transparencia.
Haga clic aquí para que una clase de ayuda establezca
ColorFilter
todos los elementos de diseño de un menú, incluido el icono de desbordamiento.En
onCreateOptionsMenu(Menu menu)
solo llamarMenuColorizer.colorMenu(this, menu, color);
después de inflar su menú y listo; sus iconos están teñidos.fuente
app:iconTint
El atributo se implementaSupportMenuInflater
desde la biblioteca de soporte (al menos en 28.0.0).Probado con éxito con API 15 y superior.
Archivo de recursos del menú:
(En este caso,
?attr/appIconColorEnabled
era un atributo de color personalizado en los temas de la aplicación y los recursos del icono eran elementos de diseño vectoriales).fuente
android:iconTint
yandroid:iconTintMode
no funciona, pero prefijar con enapp:
lugar deandroid:
funciona como un encanto (en mis propios elementos de diseño vectoriales, API> = 21)SupportMenuInflater
no se aplicará ninguna lógica personalizada si el menú no es un meSupportMenu
gustaMenuBuilder
, simplemente vuelve a la normalidadMenuInflater
.AppCompatActivity.startSupportActionMode(callback)
y las implementaciones de soporte apropiadas deandroidx.appcompat
se pasarán a la devolución de llamada.Personalmente preferí este enfoque desde este enlace.
Cree un diseño XML con lo siguiente:
y haga referencia a este elemento de dibujo desde su menú:
fuente
bitmap
. Hay otras formas de colorear vectores. Quizás alguien podría añadir vector de coloración aquí también ...La mayoría de las soluciones en este hilo usan una API más nueva, o usan la reflexión, o usan la búsqueda de vista intensiva para llegar al inflado
MenuItem
.Sin embargo, hay un enfoque más elegante para hacer eso. Necesita una barra de herramientas personalizada, ya que su caso de uso de "aplicar tinte personalizado" no funciona bien con la API de estilo / tematización pública.
Solo asegúrese de llamar a su código de Actividad / Fragmento:
Sin reflejo, sin búsqueda de vistas y sin tanto código, ¿eh?
Y ahora puedes ignorar lo ridículo
onCreateOptionsMenu/onOptionsItemSelected
.fuente
Menu#getItem()
complejidad es O (1) en la barra de herramientas, porque los elementos se almacenan en ArrayList. Que es diferente delView#findViewById
recorrido (al que me referí como búsqueda de vista en mi respuesta), cuya complejidad está lejos de ser constante :-)Aquí está la solución que utilizo; puede llamarlo después de onPrepareOptionsMenu () o el lugar equivalente. El motivo de mutate () es si utiliza los iconos en más de una ubicación; sin el mutado, todos adquirirán el mismo tono.
Esto no se encargará del desbordamiento, pero para eso, puede hacer esto:
Diseño:
Estilos:
Esto funciona a partir de appcompat v23.1.0.
fuente