Ubah warna yang dapat digambar secara terprogram


139

Saya mencoba mengubah warna pada gambar marker putih dengan kode. Saya telah membaca bahwa kode di bawah ini harus berubah warna, tetapi spidol saya tetap putih.

Drawable.setColorFilter( 0xffff0000, Mode.MULTIPLY )

Apakah saya melewatkan sesuatu? Apakah ada cara lain untuk mengubah warna pada drawables saya yang terletak di folder res saya?


jawaban yang diterima tidak berfungsi untuk saya..menggunakan ini Cara Menjawab [1], [1]: stackoverflow.com/questions/5940825/…
sham.y

Saya pikir semua jawaban di sini mengubah warna latar belakang, tetapi bukan warna gambar. Saya benar? adakah yang bisa memberi tahu saya? Saya mencoba semua solusi di sini dan juga pada pertanyaan yang sama pada stackoverflow, tetapi mereka hanya mengubah warna latar belakang pada kasus yang sama. Jadi saya pikir, kita hanya bisa mengubah warna latar belakang, tetapi bukan warna gambar. Aku benar?
Shirish Herwade

Jawaban:


258

Coba ini:

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

Penggunaan DrawableCompatpenting karena memberikan kompatibilitas ke belakang dan perbaikan bug pada perangkat API 22 dan sebelumnya.


Hmm, warnanya tetap putih. Mungkinkah ini berkaitan dengan kelas hello mapview OverlayItemsyang mungkin menyebabkan masalah? Ini dapat ditarik secara teratur dari folder res saya, tidak ada yang istimewa ...
Johan

jadi apa solusinya?
speedynomads

@ ρяσѕρєяK Anda sangat mengagumkan. sangat membantu
luttu android

30
Anda mungkin lebih suka PorterDuff.Mode.SRC_IN jika Anda ingin itu bekerja dengan rentang warna sumber yang lebih luas.
Lorne Laliberte

1
PorterDuffColorFilter constructor mengambil format warna ARGB
RichX

124

Anda dapat mencoba ini untuk menggambar vektor svg

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

4
Cara terbaik yang pernah saya lihat untuk svg.
apSTRK

1
lebih suka ini daripada jawaban yang diterima, meskipun keduanya akan bekerja, tetapi dengan yang ini saya tidak perlu khawatir tentang apa yang dapat diatur, saya hanya mendapatkan yang sudah ada di sana, dan itu juga kompatibel ke belakang, hebat!
RJFares

1
Jawaban terbaik ketika tidak ada yang berhasil, tidak berfungsi seperti pesona! Terima kasih banyak! Catatan: Ini juga bekerja ketika Anda memiliki ditarik xml di imageView Anda / AppCompatImageView
Sjd

1
Bagaimana cara menghapusnya secara terprogram?
Hardik Joshi

1
@HardikJoshi Documentation mengatakan: Untuk menghapus warna,nullDrawable#setTintList(ColorStateList)
lanjutkan

23

Anda mungkin perlu memanggil mutate () pada drawable atau kalau tidak semua ikon terpengaruh.

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

Cara lain untuk melakukan ini di Lollipop, android 5. + adalah mengatur warna pada bitmap yang dapat digambar seperti:

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

Ini akan bekerja untuk Anda jika Anda memiliki jumlah warna terbatas yang ingin Anda gunakan pada drawables Anda. Lihat posting blog saya untuk informasi lebih lanjut .


2
Bagus! Btw, ini sepertinya bekerja dengan baik pada pre-Lollipop juga. (Baru diuji dengan minSdkVersion 16perangkat Android 4.1.1 ini.)
Jonik

Saat membuat bitmap dengan cara ini, itu tidak melebar agar sesuai dengan tata letak seperti saat menggunakannya android:background="...". Cukup aneh!
Pangeran

Saya pikir itu karena Anda tidak membuat sembilan tambalan di sini.
MinceMan

Maaf halaman ini tidak ada = (
Phan Van Linh

@Jonik Jawaban dalam pertanyaan yang Anda berikan tidak relevan. Pertanyaan ini meminta cara untuk mengubah Drawable 's warna, tidak ImageView.
Antony.H

19

Anda dapat mencoba ini ImageView. menggunakan setColorFilter().

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

10

Saya telah menulis fungsi generik di mana Anda dapat melewatkan konteks, ikon id idable / ikon gambar mipmap dan warna baru yang Anda butuhkan untuk ikon itu.

Fungsi ini mengembalikan drawable.

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

Anda bisa mencoba ColorMatrixColorFilter, karena warna kunci Anda putih:

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

Ini berhasil untuk saya. Pastikan untuk meletakkan "ff" antara 0x dan kode warna. Seperti ini 0xff2196F3

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

Hai @ Selamat datang di stackoverflow. Jika ini berhasil untuk Anda, akan sangat membantu untuk menyertakan jsfiddle dengan solusi minimal untuk menunjukkan hal itu. Ini akan membantu orang yang memposting pertanyaan untuk memahami dengan benar.
Arjun Chaudhary

6

Sama seperti jawaban yang diterima tetapi metode kenyamanan yang lebih sederhana:

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

Catatan, kode di sini adalah Kotlin.


3

Anda mungkin ingin mencoba Mode.LIGHTENatau Mode.DARKEN. Android Javadocs mengerikan dalam menjelaskan apa yang dilakukan Mode PorterDuff. Anda dapat melihatnya di sini: PorterDuff | Android

Saya sarankan melihat-lihat di Compositing di situs Mozilla di sini. (Mereka tidak memiliki semua mode yang android lakukan tetapi mereka memiliki banyak dari mereka)


3

Gunakan ini: Untuk java

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

untuk Kotlin

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

Anda dapat menggunakan PorterDuff.Mode.SRC_ATOP, jika latar belakang Anda memiliki sudut membulat dll.


1

Sintaksis

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

Contoh

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

0

Inilah yang saya lakukan:

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

Cukup gunakan

    android:drawableTint="@color/primary_color"

dalam file XML Anda. Ganti primary_color ke warna kustom


0

Buat Metode seperti ini:

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

dan gunakan seperti itu:

    changeIconColor(this,R.drawable.ic_home);

0

Cara termudah untuk melakukannya:

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

atau

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

a, r, g, b: Nilai warna argb.


Ini hanya akan berfungsi jika OP akan menggunakan imageViews daripada drawable.
Menabur Serat

0

Bagi mereka yang menggunakan Kotlin fungsi ekstensi sederhana:

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

dan kemudian lakukan

background.tint(context, R.color.colorPrimary)
Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.