Changer la couleur de dessin par programmation


139

J'essaye de changer la couleur sur une image de marqueur blanc par code. J'ai lu que le code ci-dessous devrait changer la couleur, mais mon marqueur reste blanc.

Drawable.setColorFilter( 0xffff0000, Mode.MULTIPLY )

Ai-je oublié quelque chose? Existe-t-il un autre moyen de changer les couleurs de mes drawables situés dans mon dossier res?


réponse acceptée n'a pas fonctionné pour moi .. a utilisé ceci Comment répondre [1], [1]: stackoverflow.com/questions/5940825/…
sham.y

Je pense que toutes les réponses ici changent la couleur de fond, mais pas la couleur de l'image. J'ai raison? Quelqu'un peut-il me dire s'il vous plaît? J'ai essayé toutes les solutions ici et aussi sur les mêmes questions sur stackoverflow, mais elles ne changent que la couleur de fond au cas où. Donc je pense que nous ne pouvons changer que la couleur de fond, mais pas la couleur des images. J'ai raison?
Shirish Herwade

Réponses:


258

Essaye ça:

Drawable unwrappedDrawable = AppCompatResources.getDrawable(context, R.drawable.my_drawable); 
Drawable wrappedDrawable = DrawableCompat.wrap(unwrappedDrawable);
DrawableCompat.setTint(wrappedDrawable, Color.RED);    

L'utilisation DrawableCompatest importante car elle fournit une compatibilité descendante et des corrections de bogues sur les appareils API 22 et versions antérieures.


Hmm, la couleur reste blanche. Cela pourrait-il avoir à voir avec la OverlayItemsclasse hello mapview qui pourrait causer le problème? C'est un tirage régulier de mon dossier res, rien de spécial ...
Johan

alors quelle était la solution?
speedynomads

@ ρяσѕρєяK vous êtes très génial.très utile
Luttu Android

30
Vous pouvez préférer PorterDuff.Mode.SRC_IN si vous souhaitez qu'il fonctionne avec une plus large gamme de couleurs source.
Lorne Laliberte

1
Le constructeur PorterDuffColorFilter prend le format de couleur ARVB
RichX

124

Vous pouvez essayer ceci pour dessiner un vecteur svg

DrawableCompat.setTint(
    DrawableCompat.wrap(myImageView.getDrawable()),
    ContextCompat.getColor(context, R.color.another_nice_color)
);

4
Meilleur moyen que j'ai vu pour svg.
apSTRK

1
préférez cela à la réponse acceptée, bien que les deux fonctionneront, mais avec celui-ci, je n'ai pas à m'inquiéter du dessinable à définir, je viens d'obtenir celui qui est déjà là, et il est également rétrocompatible, super!
RJFares

1
Meilleure réponse quand rien n'a fonctionné iot fonctionne comme un charme! Merci beaucoup! Remarque: cela fonctionne également lorsque vous avez un dessin xml dans votre imageView / AppCompatImageView
Sjd

1
Comment le supprimer par programme?
Hardik Joshi

1
@HardikJoshi Documentation dit: Pour effacer la teinte, passez nullàDrawable#setTintList(ColorStateList)
arekolek

23

Vous devrez peut-être appeler mutate () sur le dessinable ou bien toutes les icônes sont affectées.

Drawable icon = ContextCompat.getDrawable(getContext(), R.drawable.ic_my_icon).mutate();
TypedValue typedValue = new TypedValue();
getContext().getTheme().resolveAttribute(R.attr.colorIcon, typedValue, true);
icon.setColorFilter(typedValue.data, PorterDuff.Mode.SRC_ATOP);

21

Une autre façon de faire cela sur Lollipop, Android 5. + consiste à définir une teinte sur un bitmap pouvant être dessiné comme tel:

<?xml version="1.0" encoding="utf-8"?>
<bitmap
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:src="@drawable/ic_back"
    android:tint="@color/red_tint"/>

Cela fonctionnera pour vous si vous avez un nombre limité de couleurs que vous souhaitez utiliser sur vos tableaux. Consultez mon article de blog pour plus d'informations .


2
Agréable! Btw, cela semble aussi bien fonctionner sur pré-Lollipop. (Je viens de tester cela avec un minSdkVersion 16appareil Android 4.1.1.)
Jonik

Lors de la création d'une image bitmap de cette façon, elle ne s'étire pas pour s'adapter à la mise en page comme elle le ferait lors de l'utilisation android:background="...". Assez étrange!
Prince

Je pense que c'est parce que vous ne créez pas un neuf patch ici.
MinceMan

Désolé cette page n'existe pas = (
Phan Van Linh

@Jonik Les réponses à votre question fournie ne sont pas pertinentes. Cette question demande comment changer la couleur de Drawable , pas ImageView.
Antony.H

19

Vous pouvez essayer ceci pour ImageView. en utilisant setColorFilter().

imageViewIcon.setColorFilter(ContextCompat.getColor(context, R.color.colorWhite));

10

J'ai écrit une fonction générique dans laquelle vous pouvez passer le contexte, l'icône est une icône d'image dessinable / mipmap id et la nouvelle couleur dont vous avez besoin pour cette icône.

Cette fonction renvoie un dessinable.

public static Drawable changeDrawableColor(Context context,int icon, int newColor) {
    Drawable mDrawable = ContextCompat.getDrawable(context, icon).mutate(); 
    mDrawable.setColorFilter(new PorterDuffColorFilter(newColor, PorterDuff.Mode.SRC_IN)); 
    return mDrawable;
} 

changeDrawableColor(getContext(),R.mipmap.ic_action_tune, Color.WHITE);

9

Vous pouvez essayer un ColorMatrixColorFilter, car votre couleur principale est le blanc:

// Assuming "color" is your target color
float r = Color.red(color) / 255f;
float g = Color.green(color) / 255f;
float b = Color.blue(color) / 255f;

ColorMatrix cm = new ColorMatrix(new float[] {
        // Change red channel
        r, 0, 0, 0, 0,
        // Change green channel
        0, g, 0, 0, 0,
        // Change blue channel
        0, 0, b, 0, 0,
        // Keep alpha channel
        0, 0, 0, 1, 0,
});
ColorMatrixColorFilter cf = new ColorMatrixColorFilter(cm);
myDrawable.setColorFilter(cf);

7

Cela a fonctionné pour moi. Assurez-vous de mettre "ff" entre 0x et le code couleur. Comme ça 0xff2196F3

Drawable mDrawable = ContextCompat.getDrawable(MainActivity.this,R.drawable.ic_vector_home);
                    mDrawable.setColorFilter(new
                            PorterDuffColorFilter(0xff2196F3,PorterDuff.Mode.SRC_IN));

Salut @Bek, bienvenue sur stackoverflow. Si cela fonctionnait pour vous, il serait très utile d'inclure un jsfiddle avec une solution minimale pour le montrer. Cela aidera la personne qui a posé la question à bien comprendre.
Arjun Chaudhary

6

Identique à la réponse acceptée mais une méthode de commodité plus simple:

val myDrawable = ContextCompat.getDrawable(context, R.drawable.my_drawable)
myDrawable.setColorFilter(Color.GREEN, PorterDuff.Mode.SRC_IN)
setCompoundDrawablesWithIntrinsicBounds(myDrawable, null, null, null)

Notez que le code ici est Kotlin.


3

Vous voudrez peut-être essayer Mode.LIGHTENou Mode.DARKEN. Les Javadocs Android expliquent horriblement ce que font les modes PorterDuff. Vous pouvez les consulter ici: PorterDuff | Android

Je suggère de regarder autour de Compositing sur le site de Mozilla ici. (Ils n'ont pas tous les modes d'Android mais ils en ont beaucoup)


3

Utilisez ceci: pour java

view.getBackground().setColorFilter(Color.parseColor("#343434"), PorterDuff.Mode.SRC_OVER)

pour Kotlin

view.background.setColorFilter(Color.parseColor("#343434"),PorterDuff.Mode.SRC_OVER)

vous pouvez utiliser PorterDuff.Mode.SRC_ATOP, si votre arrière-plan a des coins arrondis, etc.


1

Syntaxe

"your image name".setColorFilter("your context".getResources().getColor("color name"));

Exemple

myImage.setColorFilter(mContext.getResources().getColor(R.color.deep_blue_new));

0

C'est ce que j'ai fait:

public static Drawable changeDrawableColor(int drawableRes, int colorRes, Context context) {
    //Convert drawable res to bitmap
    final Bitmap bitmap = BitmapFactory.decodeResource(context.getResources(), drawableRes);
    final Bitmap resultBitmap = Bitmap.createBitmap(bitmap, 0, 0,
            bitmap.getWidth() - 1, bitmap.getHeight() - 1);
    final Paint p = new Paint();
    final Canvas canvas = new Canvas(resultBitmap);
    canvas.drawBitmap(resultBitmap, 0, 0, p);

    //Create new drawable based on bitmap
    final Drawable drawable = new BitmapDrawable(context.getResources(), resultBitmap);
    drawable.setColorFilter(new
            PorterDuffColorFilter(context.getResources().getColor(colorRes), PorterDuff.Mode.MULTIPLY));
    return drawable;
}

0

Utilisez simplement

    android:drawableTint="@color/primary_color"

dans votre fichier XML. Remplacer primary_color par une couleur personnalisée


0

Créez une méthode comme celle-ci:

//CHANGE ICON COLOR
private void changeIconColor(Context context ,int drawable){
    Drawable unwrappedDrawable = AppCompatResources.getDrawable(context, drawable);
    assert unwrappedDrawable != null;
    Drawable wrappedDrawable = DrawableCompat.wrap(unwrappedDrawable);
    DrawableCompat.setTint(wrappedDrawable, getResources().getColor(R.color.colorAccent));
}

et utilisez-le comme ça:

    changeIconColor(this,R.drawable.ic_home);

0

Façon la plus simple de le faire:

imageView.setColorFilter(Color.rgb(r, g b));

ou

imageView.setColorFilter(Color.argb(a, r, g, b));

a, r, g, b: valeurs d'argb de couleur.


Cela ne fonctionnera que si l'OP devait utiliser imageViews au lieu de drawables.
SowingFiber

0

Pour ceux qui utilisent Kotlin une simple fonction d'extension:

fun Drawable.tint(context: Context,  @ColorRes color: Int) {
    DrawableCompat.setTint(this, context.resources.getColor(color, context.theme))
}

et puis simplement faire

background.tint(context, R.color.colorPrimary)
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.