J'essaie de teinter une image avant Android API niveau 21. J'ai réussi à teinter des éléments en utilisant:
<Android:tint="@color/red"/>
Cependant, je n'arrive pas à comprendre comment le faire via du code sur une ImageView:
Drawable iconDrawable = this.mContext.getResources().getDrawable(R.drawable.somedrawable);
DrawableCompat.setTint(iconDrawable, this.mContext.getResources().getColor(R.color.red));
imageView.setImageDrawable(iconDrawable);
J'ai essayé de régler le TintMode mais cela ne semble pas faire de différence. Suis-je en train d'utiliser incorrectement la classe de compatibilité v4 DrawableCompat?
La façon la plus simple de teinter multiplateforme (si vous n'avez pas besoin d'un ColorStateList) est:
drawable.mutate().setColorFilter(color, PorterDuff.Mode.SRC_IN);
N'oubliez pas de muter le Drawable avant d'appliquer le filtre.
Dans le cas où quelqu'un a besoin d'utiliser la teinture de DrawableCompat
sans affecter les autres tirables, voici comment vous le faites avec 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));
Qui peut être simplifié pour:
Drawable drawable = getResources().getDrawable(R.drawable.some_drawable);
drawable = DrawableCompat.wrap(drawable);
DrawableCompat.setTint(drawable.mutate(), getResources().getColor(R.color.white));
Auparavant, la teinture n'était pas prise en charge par DrawableCompat
. À partir de la bibliothèque de support 22.1, vous pouvez le faire, mais vous devez le faire de cette manière:
Drawable normalDrawable = getResources().getDrawable(R.drawable.drawable_to_tint);
Drawable wrapDrawable = DrawableCompat.wrap(normalDrawable);
DrawableCompat.setTint(wrapDrawable, getResources().getColor(R.color.colorPrimaryLight));
Les réponses ici ne fonctionnent pas pour les appareils pré-Lollipop (SupportLib 23.4.0) mais j'ai posté une solution de contournement qui fonctionne pour l'API 17 et plus: https://stackoverflow.com/a/37434219/ 2170109
Le code suivant a été testé et fonctionne sur les API 17, 19, 21, 22, 23 et N Preview 3:
// https://stackoverflow.com/a/30928051/2170109
Drawable drawable = DrawableCompat.wrap(ContextCompat.getDrawable(context, R.drawable.vector));
image.setImageDrawable(drawable);
/*
* need to use the filter | https://stackoverflow.com/a/30880522/2170109
* (even if compat should use it for pre-API21-devices | https://stackoverflow.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 vous regardez le code source de DrawableCompat, vous verrez que pour toute version <21 la méthode ne fait rien .
L'idée de DrawableCompat semble simplement ne pas planter sur les anciennes versions, plutôt que de fournir réellement cette fonctionnalité.
Avec la bibliothèque de support 22.1, vous pouvez utiliser DrawableCompat pour teinter les tirages.
DrawableCompat.wrap (Drawable) et setTint (), setTintList () et setTintMode () fonctionneront juste: pas besoin de créer et de maintenir des drawables séparés uniquement pour prendre en charge plusieurs couleurs!
Je vais partager ma solution ici car cela peut faire gagner du temps à quelqu'un.
J'avais un ImageView
avec vector drawable utilisé comme source drawable (en fait, c'était Support Vector Drawable from Android Support Library 23.3). Donc, d'abord je l'ai enveloppé comme ça:
mImageView.setImageDrawable(DrawableCompat.wrap(mImageView.getDrawable()));
Et après cela, j'ai essayé d'appliquer une teinte comme ceci:
DrawableCompat.setTint(
mImageView.getDrawable(),
getResources().getColor(R.color.main_color)
);
Pas de chance.
J'ai essayé d'appeler mutate()
sur le drawable enveloppé, ainsi que sur le drawable original - toujours pas de chance. invalidate()
appelé mImageView
a fait l'affaire.