studio - Android: Tinte utilizando DrawableCompat
set image view android (7)
Anteriormente, el tintado no era compatible con DrawableCompat
. A partir de la biblioteca de soporte 22.1 puede hacerlo, pero necesita hacerlo de esta manera:
Drawable normalDrawable = getResources().getDrawable(R.drawable.drawable_to_tint);
Drawable wrapDrawable = DrawableCompat.wrap(normalDrawable);
DrawableCompat.setTint(wrapDrawable, getResources().getColor(R.color.colorPrimaryLight));
Estoy tratando de teñir una imagen antes del nivel 21 de la API de Android. He teñido artículos con éxito usando:
<android:tint="@color/red"/>
Sin embargo, parece que no puedo descubrir cómo hacer esto a través del código en un ImageView:
Drawable iconDrawable = this.mContext.getResources().getDrawable(R.drawable.somedrawable);
DrawableCompat.setTint(iconDrawable, this.mContext.getResources().getColor(R.color.red));
imageView.setImageDrawable(iconDrawable);
He intentado configurar el TintMode pero esto no parece ser diferente. ¿Estoy usando la clase de compatibilidad v4 DrawableCompat incorrectamente?
Compartiré mi solución aquí porque puede ahorrarle tiempo a alguien.
Tuve un ImageView
con vector dibujable utilizado como fuente dibujable (en realidad, fue Soporte Vector Dibujable from Biblioteca de Soporte de Android 23.3). Entonces, primero lo he envuelto así:
mImageView.setImageDrawable(DrawableCompat.wrap(mImageView.getDrawable()));
Y después de eso traté de aplicarle un tinte así:
DrawableCompat.setTint(
mImageView.getDrawable(),
getResources().getColor(R.color.main_color)
);
Sin suerte.
Intenté llamar a mutate()
en drawable envuelto, así como en drawable original, aún sin suerte. invalidate()
llamado en mImageView
hizo el truco.
Con la biblioteca de soporte 22.1 puede usar DrawableCompat para tintar dibujables.
DrawableCompat.wrap (Drawable) y setTint (), setTintList () y setTintMode () solo funcionarán: ¡no es necesario crear y mantener dibujables separados solo para admitir varios colores!
En caso de que alguien necesite usar el tintado de DrawableCompat
sin afectar otros dibujables, así es como lo hace con mutate()
:
Drawable drawable = getResources().getDrawable(R.drawable.some_drawable);
Drawable wrappedDrawable = DrawableCompat.wrap(drawable);
wrappedDrawable = wrappedDrawable.mutate();
DrawableCompat.setTint(wrappedDrawable, getResources().getColor(R.color.white));
Que se puede simplificar para:
Drawable drawable = getResources().getDrawable(R.drawable.some_drawable);
drawable = DrawableCompat.wrap(drawable);
DrawableCompat.setTint(drawable.mutate(), getResources().getColor(R.color.white));
La forma más sencilla de tintar multiplataforma (si no necesita un ColorStateList) es:
drawable.mutate().setColorFilter(color, PorterDuff.Mode.SRC_IN);
No olvides mutar el Drawable antes de aplicar el filtro.
Las respuestas aquí no funcionan para dispositivos pre-lollipop (SupportLib 23.4.0) pero he publicado una solución que funciona para API 17 y superior: https://.com/a/37434219/2170109
El siguiente código fue probado y está trabajando en las API 17, 19, 21, 22, 23 y N Preview 3:
// https://.com/a/30928051/2170109
Drawable drawable = DrawableCompat.wrap(ContextCompat.getDrawable(context, R.drawable.vector));
image.setImageDrawable(drawable);
/*
* need to use the filter | https://.com/a/30880522/2170109
* (even if compat should use it for pre-API21-devices | https://.com/a/27812472/2170109)
*/
int color = ContextCompat.getColor(context, R.color.yourcolor);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
DrawableCompat.setTint(drawable, color);
} else {
drawable.mutate().setColorFilter(color, PorterDuff.Mode.SRC_IN);
}
Si observa el código fuente de DrawableCompat, verá que para cualquier versión <21 el método no hace nada .
La idea de DrawableCompat parece que simplemente no falla en las versiones antiguas, en lugar de proporcionar esa funcionalidad.