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?

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

ρяσѕρєя K
sumber
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)
);
amorenew
sumber
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);
pemalu
sumber
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 .

Tuan Putra
sumber
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));
Jaydip Meghapara
sumber
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);
Sachin Tanpure
sumber
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);
tiguchi
sumber
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));
Bek
sumber
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.

CorayThan
sumber
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)

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

Ravi. Dudi
sumber
1

Sintaksis

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

Contoh

myImage.setColorFilter(mContext.getResources().getColor(R.color.deep_blue_new));
Om Prakash Sharma
sumber
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;
}
Edwin
sumber
0

Cukup gunakan

    android:drawableTint="@color/primary_color"

dalam file XML Anda. Ganti primary_color ke warna kustom

Arvina Kori
sumber
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);
sana ebadi
sumber
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.

Anubhav
sumber
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)
Chapz
sumber