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

398

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 ...

Alexander Farber
la source
15
Vous avez peut-être utilisé l'ID de ressource entier au lieu de la valeur de couleur entière, essayez de convertir R.color.blue en getResources (). GetColor (R.color.blue)
milosmns
Drawable drawable = ...; drawable.setColorFilter (ContextCompat.getColor (context, R.color.white), PorterDuff.Mode.DST); imageView.setImageDrawable (dessinable); // n'importe quelle couleur peut être utilisée ici
flame3

Réponses:

917

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

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

Si vous voulez une 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);

MISE À JOUR :
@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.

Hardik
la source
12
En xml, android: tint = "@ color / blue"
Luis
1
Plus Android: la teinte est de 21+
androidguy
8
android:tintfonctionne sur toutes les versions Android. Vous parlez peut-être drawableTint?
finstas
11
PorterDuff.Mode.MULTIPLY ne fonctionne pas dans ma situation j'ai utilisé PorterDuff.Mode.SRC_IN et cela fonctionne
Mohamed Nageh
236

La plupart des réponses se réfèrent à l'utilisation setColorFilter qui n'est pas ce qui a é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 ImageViewCompat:

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

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

ContextCompat.getColor(context, R.color.blue);
ADev
la source
6
Doit être la réponse acceptée. Notez qu'il ne fonctionne que sur les ImageViewinstances xml avec le thème AppCompat ou sur les AppCompatImageViewsous-classes.
Louis CAD du
1
@ADev apprécie votre solution mais la question a été posée en 2013 et les versions ImageViewCompat et AppCompatImageView avec prise en charge v4 lib 25.4.0 en juin 2017 et 25.1.0 décembre 2016 respectivement :)
Hardik
1
@ADev bien sûr, mais vous n'avez pas mentionné correctement dans votre réponse que votre solution est nouvelle et nécessite une bibliothèque de support plus récente 25.4.0 et supérieure car avec une version inférieure de support lib cette classe n'est pas disponible, donc personne ne pourrait la trouver !! !! par la façon dont j'ai édité la réponse :) bonne journée ...
Hardik
Cela ne fonctionne pas sur l'API 16.
Tayyab Mazhar
50

Cela a fonctionné pour moi

mImageView.setColorFilter(ContextCompat.getColor(getContext(), R.color.green_500));
toobsco42
la source
ouais, a fonctionné pour moi aussi, sans le deuxième paramètre .. ça peut aussi allermImageView.setColorFilter(getContext().getResources().getColor(R.color.green_500));
Biskrem Muhammad
voté et sans le deuxième paramètre, il fonctionne comme un charme. Thx @ toobsco42
Ravi Vaniya
35

@Hardik a raison. L'autre erreur dans votre code est lorsque vous référencez votre couleur définie par XML. Vous avez transmis uniquement l'ID à la setColorFilterméthode, lorsque vous devez utiliser l'ID pour localiser la ressource couleur et transmettre la ressource à la setColorFilterméthode. Réécriture de votre code d'origine ci-dessous.

Si cette ligne fait partie de 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 cela est également vrai pour les autres types de ressources, tels que les entiers, les bools, les dimensions, etc. À l'exception de la chaîne, que vous pouvez utiliser directement getString()dans votre activité sans avoir à appeler au préalable.getResources() (ne me demandez pas pourquoi) .

Sinon, votre code semble bon. (Même si je n'ai pas setColorFiltertrop étudié la méthode ...)

CrepeGoat
la source
22

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

J'obtiens la solution en utilisant un autre PortDuff.MODE.

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

À partir de Lollipop, il existe également une méthode de 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 désormais utiliser la bibliothèque DrawableCompat

Tad
la source
2
en fait, la bibliothèque de support le prend en charge. voir ma réponse: stackoverflow.com/a/34479043/878126
développeur android
13

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

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

Usage:-

imageView.setTint(R.color.tintColor)
Manohar Reddy
la source
Existe-t-il un modèle similaire pour la teinte de texte de Button / TextView?
développeur Android
voulez-vous dire la couleur ou la teinte du texte textview pour textview dessinable?
Manohar Reddy
Je veux dire "teinte du texte". La couleur du texte. Mais je pense que c'est assez problématique, car le texte a une couleur pour chaque état ... Encore une fois, comment cela fonctionne-t-il bien lorsque je définis la couleur d'accentuation ... Impair .... Est-il possible de définir la couleur d'accentuation sur un bouton spécifique (ou TextView), par programme?
développeur Android
12

Essaye ça. Il devrait fonctionner sur toutes les versions d'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 l'un des éléments ci-dessus pour le faire fonctionner.

Vous pouvez lire sur les fonctionnalités plus intéressantes de DrawableCompat sur les documents, ici .

développeur android
la source
1
Je devais aussi faire imageView.getBackground()pour obtenir le drawable, car imageView.getDrawable()retournait null.
Rock Lee
@RockLee assurez-vous que vous avez utilisé src dans l'image vue xml ou setImageResource dans le code
orelzion
c'est le moyen idéal pour définir la couleur de la teinte pour le fond de la vue d'image
leegor
11

Si votre couleur a une transparence hexadécimale, utilisez le code ci-dessous.

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

Pour effacer la teinte

ImageViewCompat.setImageTintList(imageView, null);
Sai
la source
quel est le type de "img"
Beyaz
1
@Beyaz imgest de type ImageView.
Sai
10

Simple et une ligne

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

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 l'API 21+, mais pour moi, ce n'était pas un problème. Vous pouvez utiliser un ImageViewCompat pour résoudre ce problème, tho.

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

Felix
la source
7

À partir de Lollipop, il existe une méthode appelée ImageView#setImageTintList()que vous pouvez utiliser ... l'avantage étant qu'il prend une ColorStateListcouleur par opposition à une seule, rendant ainsi la teinte de l'image sensible à l'état.

Sur les appareils pré-Lollipop, vous pouvez obtenir le même comportement en teintant le dessinable puis en le définissant comme ImageViewdessinable de l'image:

ColorStateList csl = AppCompatResources.getColorStateList(context, R.color.my_clr_selector);
Drawable drawable = DrawableCompat.wrap(imageView.getDrawable());
DrawableCompat.setTintList(drawable, csl);
imageView.setImageDrawable(drawable);
Alex Lockwood
la source
6
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);
Pawan asati
la source
6

Pour définir la teinte d'une vue d'image 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 :-)

Abhign01
la source
4

Ajout de adev de réponse (qui à mon avis est le plus correct), depuis l'adoption généralisée de Kotlin et 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!

Cillian Myles
la source
4

J'ai trouvé que nous pouvons utiliser le sélecteur de couleurs pour l'attrition des teintes:

mImageView.setEnabled(true);

activity_main.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>
NickUnuchek
la source
Salut, cela ne fonctionne pas pour les dessins vectoriels..Toute solution de contournement pour la même chose?
Manukumar
@Manukumar Utilisez app:srcCompatau lieu de android:srcet ajoutez-le vectorDrawables.useSupportLibrary = trueà la defaultConfigpartie de votre fichier build.gradle. Testé pour fonctionner correctement sur l'émulateur Kitkat.
développeur Android
3

Ne pas utiliser PoterDuff.Mode, utiliser setColorFilter()ça marche pour tous.

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

Comme l'a dit @milosmns, vous devez 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 principale pour laquelle votre déclaration n'a pas fonctionné.

HunkD
la source
2

Je suis en retard dans la fête mais je n'ai pas vu ma solusion ci-dessus. Nous pouvons également définir la couleur de la teinte setImageResource()(ma version minSdk est 24).

Donc, d'abord, vous devez créer un sélecteur et l'enregistrer dans /drawablele dossier d'actifs (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"/>

Ensuite, définissez-le dans un code comme celui-ci:

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

Si vous souhaitez régler le sélecteur sur votre teinte:

ImageViewCompat.setImageTintList(iv, getResources().getColorStateList(R.color.app_icon_click_color));
Yusril Maulidan Raji
la source
0

Solution Kotlin utilisant la fonction d'extension, pour définir et désactiver la teinture:

fun ImageView.setTint(@ColorInt color: Int?) {
    if (color == null) {
        ImageViewCompat.setImageTintList(this, null)
        return
    }
    ImageViewCompat.setImageTintMode(this, PorterDuff.Mode.SRC_ATOP)
    ImageViewCompat.setImageTintList(this, ColorStateList.valueOf(color))
}
développeur android
la source
-4

Pas une réponse exacte mais une alternative plus simple:

  • Placer une autre vue au-dessus de l'image
  • Modifiez la valeur alpha de la vue comme vous le souhaitez (par programme) pour obtenir l'effet souhaité.

Voici un extrait pour cela:

<FrameLayout
    android:layout_width="match_parent"
    android:layout_height="wrap_content">

    <ImageView
        android:layout_width="match_parent"
        android:layout_height="@dimen/height120"
        android:contentDescription="@string/my_description"
        android:scaleType="fitXY"
        android:src="@drawable/my_awesome_image"/>

    <View
        android:layout_width="match_parent"
        android:layout_height="@dimen/height120"
        android:alpha="0.5"
        android:background="@color/my_blue_color"/>
</FrameLayout>
Shubham Chaudhary
la source
il s'agit de teinte! pas alpha qui est pour la transparence.
David
Mais cela finit par agir comme une teinte. Vous devriez l'essayer vous-même. Ce n'est qu'une façon de voir les choses.
Shubham Chaudhary
@ShubhamChaudhary Je sais que c'est tard mais que se passe-t-il si l'image est png. Alors l'arrière-plan ne changera-t-il pas? Alpha et la teinte sont également très différents. La teinte est comme le remplacement de la couleur, si je ne me trompe pas. Aucune infraction prévue. J'essaie juste d'aider :)
KISHORE_ZE
Point valide. Cette réponse a aidé dans mon cas. L'espoir convient aussi aux chaussures de quelqu'un d'autre.
Shubham Chaudhary