Thay đổi màu vẽ được lập trình


139

Tôi đang cố gắng thay đổi màu sắc trên một hình ảnh đánh dấu màu trắng bằng mã. Tôi đã đọc được rằng mã bên dưới sẽ thay đổi màu sắc, nhưng điểm đánh dấu của tôi vẫn là màu trắng.

Drawable.setColorFilter( 0xffff0000, Mode.MULTIPLY )

Tôi đã bỏ lỡ một cái gì đó? Có cách nào khác để thay đổi màu sắc trên các ngăn kéo của tôi nằm trong thư mục res của tôi không?


câu trả lời được chấp nhận đã không làm việc cho tôi..được sử dụng này Cách trả lời [1], [1]: stackoverflow.com/questions/5940825/
trộm

Tôi nghĩ rằng tất cả các câu trả lời ở đây thay đổi màu nền, nhưng không phải màu của hình ảnh. Tôi có đúng không bất cứ ai có thể cho tôi biết? Tôi đã thử tất cả các giải pháp ở đây và cũng cho các câu hỏi tương tự trên stackoverflow, nhưng chúng chỉ thay đổi màu nền trong trường hợp có thể. Vì vậy, tôi nghĩ rằng, chúng ta chỉ có thể thay đổi màu nền, nhưng không thể thay đổi màu sắc hình ảnh. Tôi có đúng không?
Shirish Herwade

Câu trả lời:


258

Thử cái này:

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

Việc sử dụng DrawableCompatrất quan trọng vì nó cung cấp khả năng tương thích ngược và sửa lỗi trên các thiết bị API 22 trở về trước.


Hmm, màu vẫn trắng. Nó có thể liên quan đến OverlayItemslớp hello mapview có thể gây ra vấn đề không? Nó có thể rút ra thường xuyên từ thư mục res của tôi, không có gì đặc biệt ...
Johan

vì vậy giải pháp là gì?
speedynomads

@ яσѕρєяK bạn rất tuyệt vời. Rất hữu ích
luttu android

30
Bạn có thể thích PorterDuff.Mode.SRC_IN nếu bạn muốn nó hoạt động với dải màu nguồn rộng hơn.
Lorne Laliberte 16/07/2015

1
Trình xây dựng PorterDuffColorFilter có định dạng màu ARGB
RichX

124

Bạn có thể thử điều này cho vectơ vectơ

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

4
Cách tốt nhất tôi đã thấy cho svg.
apSTRK

1
thích câu trả lời hơn câu trả lời được chấp nhận, mặc dù cả hai sẽ hoạt động, nhưng với câu trả lời này tôi không phải lo lắng về việc có thể rút ra được gì, tôi chỉ cần có câu trả lời ở đó, và nó cũng tương thích ngược, thật tuyệt!
RJFares

1
Câu trả lời tốt nhất khi không có gì làm việc iot làm việc như một bùa mê! Cảm ơn rất nhiều! Lưu ý: Nó cũng làm việc cho khi bạn có thể vẽ xml trong IMAGExem bạn / AppCompatImageView
SJD

1
Làm thế nào để loại bỏ nó một cách lập trình?
Hardik Joshi

1
Tài liệu @HardikJoshi nói: Để xóa màu, hãy chuyển nullđếnDrawable#setTintList(ColorStateList)
arekolek

23

Bạn có thể cần gọi mutate () trên drawable nếu không tất cả các biểu tượng đều bị ảnh hưởng.

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

Một cách khác để làm điều này trên Lollipop, android 5. + là thiết lập một sắc thái trên bitmap có thể vẽ như sau:

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

Điều này sẽ làm việc cho bạn nếu bạn có một số lượng màu hạn chế mà bạn muốn sử dụng trên các đồ vẽ của mình. Kiểm tra bài viết trên blog của tôi để biết thêm thông tin .


2
Đẹp! Btw, điều này dường như cũng hoạt động tốt trên tiền Lollipop. (Chỉ thử nghiệm điều này với minSdkVersion 16và thiết bị Android 4.1.1.)
Jonik

Khi tạo một bitmap theo cách này, nó không kéo dài để phù hợp với bố cục như khi sử dụng android:background="...". Khá lạ!
Hoàng tử

Tôi nghĩ đó là bởi vì bạn không tạo ra một bản vá chín ở đây.
MinceMan

Xin lỗi, trang này không tồn tại = (
Phan Văn Linh

@Jonik Các câu trả lời trong câu hỏi được cung cấp của bạn là không liên quan. Câu hỏi này đang hỏi cách thay đổi màu của Drawable , không phải ImageView.
Antony.H

19

Bạn có thể thử điều này cho ImageView. sử dụng setColorFilter().

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

10

Tôi đã viết một hàm chung trong đó bạn có thể chuyển ngữ cảnh, biểu tượng là id drawable / mipmap biểu tượng hình ảnh và màu mới mà bạn cần cho biểu tượng đó.

Hàm này trả về một 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

Bạn có thể dùng thử ColorMatrixColorFilter, vì màu chính của bạn là màu trắng:

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

Điều này làm việc cho tôi. Đảm bảo đặt "ff" giữa 0x và mã màu. Thích cái này 0xff2196F3

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

Xin chào @Bek chào mừng bạn đến với stackoverflow. Nếu điều này làm việc cho bạn, sẽ rất hữu ích khi bao gồm một jsfiddle với giải pháp tối thiểu để thể hiện điều đó. Nó sẽ giúp người đăng câu hỏi để hiểu đúng.
Arjun Chaudhary

6

Giống như câu trả lời được chấp nhận nhưng một phương pháp tiện lợi đơn giản hơn:

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

Lưu ý, mã ở đây là Kotlin.


3

Bạn có thể muốn thử Mode.LIGHTENhoặc Mode.DARKEN. Các Javadocs Android thật kinh khủng khi giải thích các Chế độ PorterDuff làm gì. Bạn có thể xem chúng ở đây: PorterDuff | Android

Tôi khuyên bạn nên tìm xung quanh tại Compositing trên trang web của Mozilla tại đây. (Họ không có tất cả các chế độ mà Android làm nhưng họ có rất nhiều chế độ)


3

Sử dụng cái này: Đối với java

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

cho Kotlin

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

bạn có thể sử dụng PorterDuff.Mode.SRC_ATOP, nếu nền của bạn có các góc tròn, v.v.


1

Cú pháp

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

Thí dụ

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

0

Đây là những gì tôi đã làm:

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

Đơn giản chỉ cần sử dụng

    android:drawableTint="@color/primary_color"

trong tệp XML của bạn. Thay thế chính_color thành màu tùy chỉnh


0

Tạo phương thức như thế này:

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

và sử dụng nó như nó:

    changeIconColor(this,R.drawable.ic_home);

0

Cách dễ nhất để làm điều đó:

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

hoặc là

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

a, r, g, b: Giá trị argb màu.


Điều này sẽ chỉ hoạt động nếu OP sẽ sử dụng imageViews thay vì drawable.
SowingFiber

0

Đối với những người sử dụng Kotlin, một chức năng mở rộng đơn giản:

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

và sau đó chỉ cần làm

background.tint(context, R.color.colorPrimary)
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.