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


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.



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);

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));

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


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);

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


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)

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 .


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);

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));

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 :-)


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);

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);

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 :-)


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!


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>

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));

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


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)

2

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

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

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))
}

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

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
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.