web-dev-qa-db-fra.com

Comment définir la teinte pour une vue d'image par programme dans Android?

Besoin de définir la teinte pour une vue d'image ... Je l'utilise de la manière suivante:

imageView.setColorFilter(R.color.blue,Android.graphics.PorterDuff.Mode.MULTIPLY);

Mais ça ne change pas ...

324
user2968768

Vous pouvez changer la teinte, assez facilement dans le code via:

imageView.setColorFilter(Color.argb(255, 255, 255, 255)); // Teinte blanche

Si vous voulez la teinte de couleur alors

imageView.setColorFilter(ContextCompat.getColor(context, R.color.COLOR_YOUR_COLOR), Android.graphics.PorterDuff.Mode.MULTIPLY);

Pour vecteur dessinable

imageView.setColorFilter(ContextCompat.getColor(context, R.color.COLOR_YOUR_COLOR), Android.graphics.PorterDuff.Mode.SRC_IN);

UPDATE:
@ ADev a une solution plus récente dans sa réponse ici , mais sa solution nécessite une bibliothèque de support plus récente - 25.4.0 ou supérieure.

753
Hardik

La plupart des réponses se réfèrent à l'utilisation de setColorFilter qui n'est pas ce qui avait été demandé à l'origine.

L'utilisateur @Tad a sa réponse dans la bonne direction, mais cela ne fonctionne que sur l'API 21+.

Pour définir la teinte sur toutes les versions d'Android, utilisez le ImageViewCompat:

ImageViewCompat.setImageTintList(imageView, ColorStateList.valueOf(yourTint));

Notez que yourTint dans ce cas doit être un "color int". Si vous avez une ressource de couleur telle que R.color.blue, vous devez d'abord charger la couleur int:

ContextCompat.getColor(context, R.color.blue);
127
ADev

Cela a fonctionné pour moi

mImageView.setColorFilter(ContextCompat.getColor(getContext(), R.color.green_500));
37
toobsco42

@Hardik a raison. L'autre erreur dans votre code est lorsque vous référencez votre couleur définie par XML. Vous avez uniquement transmis l'ID à la méthode setColorFilter, lorsque vous devez utiliser l'ID pour localiser la ressource couleur, puis transmettez la ressource à la méthode setColorFilter. Réécrivez votre code original ci-dessous.

Si cette ligne est dans votre activité:

imageView.setColorFilter(getResources().getColor(R.color.blue), Android.graphics.PorterDuff.Mode.MULTIPLY);

Sinon, vous devez référencer votre activité principale:

Activity main = ...
imageView.setColorFilter(main.getResources().getColor(R.color.blue), Android.graphics.PorterDuff.Mode.MULTIPLY);

Notez que ceci est également vrai pour les autres types de ressources, tels que les entiers, les bools, les dimensions, etc. Sauf pour string, vous pouvez utiliser directement getString() dans votre activité sans avoir à appeler getResources() (ne me demandez pas Pourquoi).

Sinon, votre code a l'air bien. (Bien que je n'ai pas trop étudié la méthode setColorFilter ...)

34
CrepeGoat

Après avoir essayé toutes les méthodes et elles n’ont pas fonctionné pour moi.

Je reçois la solution en utilisant un autre PorterDuff.MODE.

imgEstadoBillete.setColorFilter(context.getResources().getColor(R.color.green),PorterDuff.Mode.SRC_IN);
17
Catluc

Depuis Lollipop, il existe également une méthode teinte pour BitmapDrawables qui fonctionne avec la nouvelle classe Palette:

public void setTintList (teinte ColorStateList)

et

public void setTintMode (PorterDuff.Mode tintMode)

Sur les anciennes versions d'Android, vous pouvez maintenant utiliser la bibliothèque DrawableCompat

12
Tad

Essaye ça. Il devrait fonctionner sur toutes les versions Android prises en charge par la bibliothèque de support:

public static Drawable getTintedDrawableOfColorResId(@NonNull Context context, @NonNull Bitmap inputBitmap, @ColorRes int colorResId) {
    return getTintedDrawable(context, new BitmapDrawable(context.getResources(), inputBitmap), ContextCompat.getColor(context, colorResId));
}

public static Drawable getTintedDrawable(@NonNull Context context, @NonNull Bitmap inputBitmap, @ColorInt int color) {
    return getTintedDrawable(context, new BitmapDrawable(context.getResources(), inputBitmap), color);
}

public static Drawable getTintedDrawable(@NonNull Context context, @NonNull Drawable inputDrawable, @ColorInt int color) {
    Drawable wrapDrawable = DrawableCompat.wrap(inputDrawable);
    DrawableCompat.setTint(wrapDrawable, color);
    DrawableCompat.setTintMode(wrapDrawable, PorterDuff.Mode.SRC_IN);
    return wrapDrawable;
}

Vous pouvez utiliser n'importe lequel des éléments ci-dessus pour le faire fonctionner.

Vous pouvez en savoir plus sur les fonctionnalités plus intéressantes de DrawableCompat dans la documentation, ici .

9
android developer

Simple et une ligne

imageView.setColorFilter(activity.getResources().getColor(R.color.your_color));
9
Gautam Surani

À partir de Lollipop, il existe une méthode appelée ImageView#setImageTintList() que vous pouvez utiliser ... l'avantage étant qu'il faut un ColorStateList au lieu d'une seule couleur, rendant ainsi la teinte de l'image sensible à l'état.

Sur les appareils antérieurs à Lollipop, vous pouvez obtenir le même comportement en colorant le dessinable, puis en le définissant comme étant l'image de ImageView:

ColorStateList csl = AppCompatResources.getColorStateList(context, R.color.my_clr_selector);
Drawable drawable = DrawableCompat.wrap(imageView.getDrawable());
DrawableCompat.setTintList(drawable, csl);
imageView.setImageDrawable(drawable);
6
Alex Lockwood
Random random=new Random;
ImageView imageView = (ImageView) view.findViewById(R.id.imageView);
ColorFilter cf = new PorterDuffColorFilter(Color.rgb(random.nextInt(255), random.nextInt(255), random.nextInt(255)),Mode.OVERLAY);

imageView.setImageResource(R.drawable.ic_bg_box);
imageView.setColorFilter(cf);
5
Pawan asati

Comme la première réponse n'a pas fonctionné pour moi:

//get ImageView
ImageView myImageView = (ImageView) findViewById(R.id.iv);

//colorid is the id of a color defined in values/colors.xml
myImageView.setImageTintList(ColorStateList.valueOf(ContextCompat.getColor(getApplicationContext(), R.color.colorid)));

Cela ne semble fonctionner que dans API 21+, mais pour moi ce n'était pas un problème. Vous pouvez utiliser un ImageViewCompat pour résoudre ce problème.

J'espère avoir aidé quelqu'un :-)

4
Felix

Si votre couleur a une transparence hexagonale, utilisez le code ci-dessous.

ImageViewCompat.setImageTintMode(img,PorterDuff.Mode.SRC_ATOP);
ImageViewCompat.setImageTintList(img,ColorStateList.valueOf(Color.parseColor("#80000000")));

Pour effacer la teinte

ImageViewCompat.setImageTintList(img, null);
4
Sai Kiran

J'ai trouvé que nous pouvons utiliser le sélecteur de couleur pour la teinte attr:

mImageView.setEnabled(true);

xml:

 <ImageView
            Android:id="@+id/image_view"
            Android:layout_width="wrap_content"
            Android:layout_height="wrap_content"
            Android:src="@drawable/ic_arrowup"
            Android:tint="@color/section_arrowup_color"
            />

section_arrowup_color.xml:

<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:Android="http://schemas.Android.com/apk/res/Android">
    <item Android:color="@Android:color/white" Android:state_enabled="true"/>
    <item Android:color="@Android:color/black" Android:state_enabled="false"/>
    <item Android:color="@Android:color/white"/>
</selector>
3
NickUnuchek

N'utilisez pas PoterDuff.Mode, utilisez setColorFilter(), cela fonctionne pour tous.

ImageView imageView = (ImageView) listItem.findViewById(R.id.imageView);
imageView.setColorFilter(getContext().getResources().getColor(R.color.msg_read));
2
Vikash Sharma

Pour définir la teinte d'une vue par programme dans Android

J'ai deux méthodes pour Android:

1)

imgView.setColorFilter(context.getResources().getColor(R.color.blue));

2)

 DrawableCompat.setTint(imgView.getDrawable(),
                     ContextCompat.getColor(context, R.color.blue));

J'espère avoir aidé quelqu'un :-)

1
Abhign01

Je suis en retard dans la soirée mais je n'ai pas vu ma solution ci-dessus. Nous sommes également en mesure de définir la couleur de teinte via setImageResource() (mon minSdkVersion est de 24).

Donc, tout d’abord, vous devez créer un sélecteur et l’enregistrer dans /drawable asset folder (je l’appelle ic_color_white_green_search.xml)

<!-- Focused and not pressed -->
<item Android:state_focused="true"
      Android:state_pressed="false">

    <bitmap Android:src="@drawable/ic_search"
            Android:tint="@color/branding_green"/>
</item>

<!-- Focused and pressed -->
<item Android:state_focused="true"
      Android:state_pressed="true">

    <bitmap Android:src="@drawable/ic_search"
            Android:tint="@color/branding_green"/>
</item>

<!-- Default -->
<item Android:drawable="@drawable/ic_search"/>

Puis définissez-le dans le code comme ceci:

val icon = itemView.findViewById(R.id.icon) as ImageButton
icon.setImageResource(R.drawable.ic_color_white_green_search)
1
Hesam

Ajout à ADevréponse (ce qui, à mon avis, est le plus correct), depuis l'adoption généralisée de Kotlin et de ses fonctions d'extension utiles:

fun ImageView.setTint(context: Context, @ColorRes colorId: Int) {
    val color = ContextCompat.getColor(context, colorId)
    val colorStateList = ColorStateList.valueOf(color)
    ImageViewCompat.setImageTintList(this, colorStateList)
}

Je pense que c'est une fonction qui pourrait être utile dans n'importe quel projet Android!

1
Cillian Myles

Meilleure fonction d'extension simplifiée grâce à ADev

fun ImageView.setTint(@ColorRes colorRes: Int) {
    ImageViewCompat.setImageTintList(this, ColorStateList.valueOf(ContextCompat.getColor(context, colorRes)))
}

Utilisation: -

imageView.setTint(R.color.tintColor)
1
Manohar Reddy

Comme @milosmns l'a dit, vous devriez utiliser imageView.setColorFilter(getResouces().getColor(R.color.blue),Android.graphics.PorterDuff.Mode.MULTIPLY);

Cette API a besoin d'une valeur de couleur au lieu d'un identifiant de ressource de couleur. C'est la raison fondamentale pour laquelle votre instruction n'a pas fonctionné.

1
HunkD

Si vous souhaitez définir le sélecteur sur votre teinte:

ImageViewCompat.setImageTintList(iv, getResources().getColorStateList(R.color.app_icon_click_color));
0

Juste pour ajouter, si vous souhaitez supprimer une couleur de teinte existante, vous pouvez la définir en couleur transparente:

mSignInButton.setColorFilter(Color.TRANSPARENT);
0
Stephen Liu