Ändern Sie die Zeichenfarbe programmgesteuert

138

Ich versuche, die Farbe eines weißen Markierungsbildes per Code zu ändern. Ich habe gelesen, dass der folgende Code die Farbe ändern sollte, aber mein Marker bleibt weiß.

Drawable.setColorFilter( 0xffff0000, Mode.MULTIPLY )

Habe ich etwas verpasst? Gibt es eine andere Möglichkeit, die Farben meiner Zeichen in meinem res-Ordner zu ändern?

Johan
quelle
akzeptierte Antwort war für keine Arbeit me..used dies wie man Antwort [1], [1]: stackoverflow.com/questions/5940825/...
sham.y
Ich denke, alle Antworten hier ändern die Hintergrundfarbe, aber nicht die Farbe des Bildes. Ich habe Recht? kann mir bitte jemand sagen Ich habe alle Lösungen hier und auch bei denselben Fragen zum Stackoverflow ausprobiert, aber sie ändern möglicherweise nur die Hintergrundfarbe. Ich denke, wir können nur die Hintergrundfarbe ändern, aber nicht die Bildfarbe. Ich habe Recht?
Shirish Herwade

Antworten:

257

Versuche dies:

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

Die Verwendung DrawableCompatist wichtig, da sie Abwärtskompatibilität und Fehlerbehebungen auf API 22-Geräten und früheren Versionen bietet.

ρяσssρєя K.
quelle
Hmm, die Farbe bleibt weiß. Könnte es mit der Hallo-Mapview- OverlayItemsKlasse zu tun haben, die das Problem verursachen könnte? Es ist ein reguläres Drawable aus meinem Res-Ordner, nichts Besonderes ...
Johan
Was war die Lösung?
Speedynomads
@ ρяσsρєяK Sie sind sehr genial. Sehr hilfreich
Luttu Android
30
Möglicherweise bevorzugen Sie PorterDuff.Mode.SRC_IN, wenn Sie möchten, dass es mit einem größeren Bereich von Quellfarben funktioniert.
Lorne Laliberte
1
PorterDuffColorFilter Konstruktor nimmt ARGB Farbformat
RichX
124

Sie können dies für svg vector drawable versuchen

DrawableCompat.setTint(
    DrawableCompat.wrap(myImageView.getDrawable()),
    ContextCompat.getColor(context, R.color.another_nice_color)
);
amorenew
quelle
4
Der beste Weg, den ich für SVG gesehen habe.
apSTRK
1
ziehe dies der akzeptierten Antwort vor, obwohl beide funktionieren werden, aber mit dieser muss ich mir keine Gedanken darüber machen, was gezeichnet werden soll, ich bekomme nur die bereits vorhandene und sie ist auch abwärtskompatibel, großartig!
RJFares
1
Beste Antwort, wenn nichts funktioniert hat, funktioniert es nicht wie ein Zauber! Vielen Dank! Hinweis: Es funktioniert auch, wenn Sie eine XML-Zeichnung in Ihrer imageView / AppCompatImageView
Sjd
1
Wie entferne ich es programmgesteuert?
Hardik Joshi
1
@ HardikJoshi Dokumentation sagt: Um den Farbton zu löschen, gehen Sie nullzuDrawable#setTintList(ColorStateList)
arekolek
23

Möglicherweise müssen Sie mutate () auf dem Drawable aufrufen, da sonst alle Symbole betroffen sind.

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);
shicky
quelle
21

Eine andere Möglichkeit, dies auf Lollipop, Android 5. +, zu tun, besteht darin, einen Farbton auf einer Bitmap festzulegen, die wie folgt gezeichnet werden kann:

<?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"/>

Dies funktioniert für Sie, wenn Sie eine begrenzte Anzahl von Farben haben, die Sie für Ihre Zeichen verwenden möchten. Weitere Informationen finden Sie in meinem Blogbeitrag .

MinceMan
quelle
2
Nett! Übrigens scheint dies auch auf Pre-Lollipop gut zu funktionieren. (Gerade getestet mit minSdkVersion 16und Android 4.1.1 Gerät.)
Jonik
Wenn Sie eine Bitmap auf diese Weise erstellen, wird sie nicht wie bei der Verwendung an das Layout angepasst android:background="...". Ziemlich seltsam!
Prinz
Ich denke, das liegt daran, dass Sie hier keinen Neun-Patch erstellen.
MinceMan
Entschuldigung, diese Seite existiert nicht = (
Phan Van Linh
@ Jonik Die Antworten in Ihrer gestellten Frage sind irrelevant. In dieser Frage wird nach der Möglichkeit gefragt , die Farbe von Drawable und nicht ImageView zu ändern .
Antony.H
19

Sie können dies für versuchen ImageView. mit setColorFilter().

imageViewIcon.setColorFilter(ContextCompat.getColor(context, R.color.colorWhite));
Jaydip Meghapara
quelle
10

Ich habe eine generische Funktion geschrieben, in der Sie den Kontext übergeben können. Das Symbol ist id drawable / mipmap image icon und die neue Farbe, die Sie für dieses Symbol benötigen.

Diese Funktion gibt ein Drawable zurück.

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);
Sachin Tanpure
quelle
9

Sie können einen ColorMatrixColorFilter ausprobieren, da Ihre Schlüsselfarbe Weiß ist:

// 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);
Tiguchi
quelle
7

Das hat bei mir funktioniert. Stellen Sie sicher, dass "ff" zwischen 0x und Farbcode steht. So 0xff2196F3

Drawable mDrawable = ContextCompat.getDrawable(MainActivity.this,R.drawable.ic_vector_home);
                    mDrawable.setColorFilter(new
                            PorterDuffColorFilter(0xff2196F3,PorterDuff.Mode.SRC_IN));
Bek
quelle
Hallo @Bek, willkommen bei stackoverflow. Wenn dies für Sie funktioniert hätte, wäre es sehr hilfreich, eine jsfiddle mit minimaler Lösung einzuschließen, um dies zu zeigen. Dies hilft der Person, die die Frage gestellt hat, richtig zu verstehen.
Arjun Chaudhary
6

Entspricht der akzeptierten Antwort, bietet jedoch eine einfachere Methode:

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

Beachten Sie, dass der Code hier Kotlin ist.

CorayThan
quelle
3

Vielleicht möchten Sie es versuchen Mode.LIGHTENoder Mode.DARKEN. Die Android Javadocs sind schrecklich darin zu erklären, was die PorterDuff-Modi tun. Sie können sie hier ansehen : PorterDuff | Android

Ich schlage vor, sich hier auf Mozillas Website nach Compositing umzusehen . (Sie haben nicht alle Modi, die Android macht, aber sie haben viele von ihnen)

sebsebmc
quelle
3

Verwenden Sie dies: Für Java

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

für Kotlin

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

Sie können PorterDuff.Mode.SRC_ATOP verwenden, wenn Ihr Hintergrund abgerundete Ecken usw. hat.

Ravi.Dudi
quelle
1

Syntax

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

Beispiel

myImage.setColorFilter(mContext.getResources().getColor(R.color.deep_blue_new));
Om Prakash Sharma
quelle
0

Das habe ich getan:

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;
}
Edwin
quelle
0

Einfach benutzen

    android:drawableTint="@color/primary_color"

in Ihrer XML-Datei. Ersetzen Sie primary_color durch eine benutzerdefinierte Farbe

Arvina Kori
quelle
0

Methode wie folgt erstellen:

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

und benutze es so:

    changeIconColor(this,R.drawable.ic_home);
Sana Ebadi
quelle
0

Der einfachste Weg, dies zu tun:

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

oder

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

a, r, g, b: Farbargb-Werte.

Anubhav
quelle
Dies funktioniert nur, wenn das OP imageViews anstelle von Drawables verwendet hätte.
SowingFiber
0

Für diejenigen, die Kotlin verwenden, eine einfache Erweiterungsfunktion:

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

und dann einfach machen

background.tint(context, R.color.colorPrimary)
Chapz
quelle