Çizilebilir rengi programlı olarak değiştirin


139

Beyaz bir işaretçi görüntünün rengini koda göre değiştirmeye çalışıyorum. Aşağıdaki kodun rengi değiştirmesi gerektiğini okudum, ancak işaretçim beyaz kalıyor.

Drawable.setColorFilter( 0xffff0000, Mode.MULTIPLY )

Bir şey mi kaçırdım? Res klasörümde bulunan çekmecelerimdeki renkleri değiştirmenin başka bir yolu var mı?


kabul edilen cevap benim için işe yaramadı ... bunu kullandı Nasıl Cevap Verilir [1], [1]: stackoverflow.com/questions/5940825/…
sham.y

Sanırım buradaki tüm cevaplar arka plan rengini değiştiriyor, ancak resmin rengini değiştirmiyor. Ben haklı mıyım? biri bana söyleyebilir mi lütfen? Buradaki tüm çözümleri ve ayrıca stackoverflow ile ilgili aynı sorular üzerinde denedim, ancak bu durumda yalnızca arka plan rengini değiştiriyorlar. Bu yüzden sadece arka plan rengini değiştirebiliriz, ancak görsellerin rengini değiştiremeyiz. Ben haklıyım
Shirish Herwade

Yanıtlar:


260

Bunu dene:

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

Kullanılması DrawableCompatAPI 22 cihazlar ve daha önce üzerinde geriye dönük uyumluluk ve hata düzeltmeleri sağladığı için önemlidir.


Hmm, renk beyaz kalıyor. OverlayItemsSoruna neden olabilecek hello mapview sınıfıyla bir ilgisi olabilir mi? Res klasörümden normal bir çekilebilir, özel bir şey yok ...
Johan

peki çözüm neydi?
speedynomads

@ ρяσѕρєяK çok harikasınız. çok yardımcı
luttu android

30
Daha geniş bir kaynak renk yelpazesiyle çalışmasını istiyorsanız PorterDuff.Mode.SRC_IN'yi tercih edebilirsiniz.
Lorne Laliberte

1
PorterDuffColorFilter yapıcısı ARGB renk biçimini alıyor
RichX

124

Bunu svg vektör çekilebilir için deneyebilirsiniz

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

4
Svg için gördüğüm en iyi yol.
Nisan

1
bunu kabul edilen cevaba tercih edin, ancak her ikisi de işe yarayacak, ancak bununla neyin çekilebilir olduğu konusunda endişelenmeme gerek yok, sadece oradayım ve aynı zamanda geriye dönük uyumlu, harika!
RJFares

1
Hiçbir şey işe yaramadığında en iyi cevap bir cazibe gibi çalışmıyor! Çok teşekkürler! Not: imageView /
AppCompatImageView

1
Programatik olarak nasıl kaldırılır?
Hardik Joshi

1
@HardikJoshi Dokümantasyon diyor ki: Renk tonunu temizlemek için nullDrawable#setTintList(ColorStateList)
adrese

23

Çekilebilir dosyada mutate () çağırmanız gerekebilir, yoksa tüm simgeler etkilenir.

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

Bunu Lollipop'ta yapmanın başka bir yolu olan android 5. +, aşağıdaki gibi bir bitmap çizilebilir bir renk tonu ayarlamaktır:

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

Çekmecelerinizde kullanmak istediğiniz sınırlı sayıda renge sahipseniz bu işinize yarayacaktır. Daha fazla bilgi için blog yazıma bakın .


2
Güzel! Btw, bu Lollipop öncesi için de iyi çalışıyor gibi görünüyor. (Bunu minSdkVersion 16ve Android 4.1.1 cihazı ile test
ettim

Bu şekilde bir bitmap oluştururken, kullanım sırasında olduğu gibi mizanpaja sığacak şekilde genişlemez android:background="...". Oldukça tuhaf!
Prens

Sanırım bunun nedeni, burada dokuz yama oluşturmuyorsunuz.
MinceMan

Üzgünüz, bu sayfa yok = (
Phan Van Linh

@Jonik Verdiğiniz sorunuzdaki cevaplar alakasız. Bu soru, ImageView'ün değil, Drawable'ın rengini değiştirmenin yolunu soruyor .
Antony.H

19

Bunu deneyebilirsiniz ImageView. kullanarak setColorFilter().

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

10

İçeriği aktarabileceğiniz genel bir işlev yazdım, simge çekilebilir / mipmap görüntü simgesi ve bu simge için ihtiyacınız olan yeni renktir.

Bu işlev bir çekilebilir döndürür.

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

Ana renginiz beyaz olduğu için ColorMatrixColorFilter'ı deneyebilirsiniz:

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

Bu benim için çalıştı. 0x ile renk kodu arasına "ff" koyduğunuzdan emin olun. Bunun gibi 0xff2196F3

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

Merhaba @Bek, stackoverflow'a hoş geldiniz. Bu sizin için işe yaradıysa, bunu göstermek için minimum çözüme sahip bir jsfiddle eklemek çok yararlı olacaktır. Soruyu gönderen kişinin doğru anlamasına yardımcı olacaktır.
Arjun Chaudhary

6

Kabul edilen cevapla aynı, ancak daha basit bir kolaylık yöntemi:

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

Not, buradaki kod Kotlin'dir.


3

Sen denemek isteyebilirsiniz Mode.LIGHTENveya Mode.DARKEN. Android Javadocları, PorterDuff Modlarının ne yaptığını açıklamada korkunç. Bunlara buradan bir göz atabilirsiniz : PorterDuff | Android

Buradaki Mozilla sitesinde Compositing'e bakmanızı öneririm . (Android'in sahip olduğu tüm modlara sahip değiller, ancak birçoğu var)


3

Bunu kullanın: Java için

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

Kotlin için

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

Arka planınız yuvarlatılmış köşelere sahipse, PorterDuff.Mode.SRC_ATOP'u kullanabilirsiniz.


1

Sözdizimi

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

Misal

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

0

Yaptığım şey bu:

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

Basitçe kullan

    android:drawableTint="@color/primary_color"

XML dosyanızda. Primary_color'u özel renkle değiştirin


0

Bunun gibi bir Yöntem oluşturun:

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

ve bunun gibi kullanın:

    changeIconColor(this,R.drawable.ic_home);

0

Bunu yapmanın en kolay yolu:

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

veya

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

a, r, g, b: Renk argb değerleri.


Bu, yalnızca OP, drawables yerine imageViews kullanıyor olsaydı işe yarar.
SowingFiber

0

Kotlin'i basit bir uzantı işlevi kullananlar için :

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

ve sonra basitçe yap

background.tint(context, R.color.colorPrimary)
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.