Làm cách nào để đặt tint cho chế độ xem hình ảnh theo chương trình trong Android?


396

Cần đặt màu cho chế độ xem hình ảnh ... Tôi đang sử dụng nó theo cách sau:

imageView.setColorFilter(R.color.blue,android.graphics.PorterDuff.Mode.MULTIPLY);

Nhưng nó không thay đổi ...


15
Bạn có thể đã sử dụng id tài nguyên số nguyên thay vì giá trị màu nguyên, hãy thử chuyển đổi R.color.blue thành getResource (). GetColor (R.color.blue)
milosmns

Drawable drawable = ...; drawable.setColorFilter (ContextCompat.getColor (bối cảnh, R.color.white), PorterDuff.Mode.DST); imageView.setImageDrawable (drawable); // bất kỳ màu nào cũng có thể được sử dụng ở đây
Flame3

Câu trả lời:


916

Bạn có thể thay đổi tông màu, khá dễ dàng trong mã thông qua:

imageView.setColorFilter(Color.argb(255, 255, 255, 255)); // Màu trắng

Nếu bạn muốn màu sắc thì

imageView.setColorFilter(ContextCompat.getColor(context, R.color.COLOR_YOUR_COLOR), android.graphics.PorterDuff.Mode.MULTIPLY);

Đối với Vector Drawable

imageView.setColorFilter(ContextCompat.getColor(context, R.color.COLOR_YOUR_COLOR), android.graphics.PorterDuff.Mode.SRC_IN);

CẬP NHẬT :
@ADev có giải pháp mới hơn trong câu trả lời của anh ấy ở đây , nhưng giải pháp của anh ấy yêu cầu thư viện hỗ trợ mới hơn - 25.4.0 trở lên.



12
Trong xml, android: tint = "@ color / blue"
Luis

1
Cộng với android: tint là 21+
androidguy 17/03/2017

8
android:tinthoạt động trên tất cả các phiên bản Android. Có lẽ bạn đang nói về drawableTint?
Finstas

11
PorterDuff.Mode.MULTIPLY không hoạt động trong tình huống của tôi, tôi đã sử dụng PorterDuff.Mode.SRC_IN và nó hoạt động
Mohamed Nageh

234

Hầu hết các câu trả lời đề cập đến việc sử dụng setColorFiltermà không phải là những gì được hỏi ban đầu.

Người dùng @Tad có câu trả lời của mình theo đúng hướng nhưng nó chỉ hoạt động trên API 21+.

Để đặt màu trên tất cả các phiên bản Android, hãy sử dụng ImageViewCompat:

ImageViewCompat.setImageTintList(imageView, ColorStateList.valueOf(yourTint));

Lưu ý rằng yourTinttrong trường hợp này phải là "int int". Nếu bạn có tài nguyên màu như thế R.color.blue, bạn cần tải int màu trước:

ContextCompat.getColor(context, R.color.blue);

6
Nên là câu trả lời được chấp nhận. Lưu ý rằng nó chỉ hoạt động trên các ImageViewphiên bản xml với chủ đề AppCompat hoặc trên các AppCompatImageViewlớp con.
Louis CAD

1
@ADev đánh giá cao giải pháp của bạn nhưng câu hỏi đã được hỏi vào năm 2013 và phát hành ImageViewCompat và AppCompatImageView với v4 hỗ trợ lib 25.4.0 vào tháng 6 năm 2017 và 25.1.0 tháng 12 năm 2016 :)
Hardik

1
@ADev tất nhiên nhưng bạn chưa đề cập đúng trong câu trả lời của mình rằng giải pháp của bạn là mới và yêu cầu thư viện hỗ trợ mới hơn 25.4.0 trở lên vì với phiên bản hỗ trợ thấp hơn lib, lớp này không có sẵn nên không ai có thể tìm thấy !! !! nhân tiện tôi đã chỉnh sửa câu trả lời :) chúc một ngày tốt lành ...
Hardik

Điều này không hoạt động trên API 16.
Tayyab Mazhar

49

Điều này làm việc cho tôi

mImageView.setColorFilter(ContextCompat.getColor(getContext(), R.color.green_500));

vâng, làm việc cho tôi quá, không có tham số thứ hai .. nó cũng có thể đimImageView.setColorFilter(getContext().getResources().getColor(R.color.green_500));
Biskrem Muhammad

nâng cấp và không có tham số thứ hai, nó hoạt động như sự quyến rũ. Thx @ toobsco42
Ravi Vaniya

35

@Hardik có quyền. Lỗi khác trong mã của bạn là khi bạn tham chiếu màu do XML xác định. Bạn chỉ truyền id cho setColorFilterphương thức, khi bạn nên sử dụng ID để định vị tài nguyên màu và truyền tài nguyên cho setColorFilterphương thức. Viết lại mã gốc của bạn dưới đây.

Nếu dòng này nằm trong hoạt động của bạn:

imageView.setColorFilter(getResources().getColor(R.color.blue), android.graphics.PorterDuff.Mode.MULTIPLY);

Khác, bạn cần tham khảo hoạt động chính của bạn:

Activity main = ...
imageView.setColorFilter(main.getResources().getColor(R.color.blue), android.graphics.PorterDuff.Mode.MULTIPLY);

Lưu ý rằng điều này cũng đúng với các loại tài nguyên khác, chẳng hạn như số nguyên, mã số, kích thước, v.v. Ngoại trừ chuỗi, bạn có thể sử dụng trực tiếp getString()trong Hoạt động của mình mà không cần gọi trước getResources()(đừng hỏi tôi tại sao) .

Nếu không, mã của bạn trông tốt. (Mặc dù tôi đã không điều tra setColorFilterphương pháp quá nhiều ...)


22

Sau khi tôi thử tất cả các phương pháp và chúng không hiệu quả với tôi.

Tôi nhận được giải pháp bằng cách sử dụng một PortDuff.MODE khác.

imgEstadoBillete.setColorFilter(context.getResources().getColor(R.color.green),PorterDuff.Mode.SRC_IN);

14

Bắt đầu với Lollipop, cũng có một phương thức pha màu cho BitmapDrawables hoạt động với lớp Palette mới:

công khai void setTintList (ColorStateList tint)

công khai void setTintMode (PorterDuff.Mode tintMode)

Trên các phiên bản Android cũ hơn, giờ đây bạn có thể sử dụng thư viện DrawableCompat


2
Trên thực tế, thư viện hỗ trợ không hỗ trợ nó. xem câu trả lời của tôi: stackoverflow.com/a 432479043/878126
nhà phát triển Android

12

Thử cái này. Nó nên hoạt động trên tất cả các phiên bản Android mà thư viện hỗ trợ hỗ trợ:

public static Drawable getTintedDrawableOfColorResId(@NonNull Context context, @NonNull Bitmap inputBitmap, @ColorRes int colorResId) {
    return getTintedDrawable(context, new BitmapDrawable(context.getResources(), inputBitmap), ContextCompat.getColor(context, colorResId));
}

public static Drawable getTintedDrawable(@NonNull Context context, @NonNull Bitmap inputBitmap, @ColorInt int color) {
    return getTintedDrawable(context, new BitmapDrawable(context.getResources(), inputBitmap), color);
}

public static Drawable getTintedDrawable(@NonNull Context context, @NonNull Drawable inputDrawable, @ColorInt int color) {
    Drawable wrapDrawable = DrawableCompat.wrap(inputDrawable);
    DrawableCompat.setTint(wrapDrawable, color);
    DrawableCompat.setTintMode(wrapDrawable, PorterDuff.Mode.SRC_IN);
    return wrapDrawable;
}

Bạn có thể sử dụng bất kỳ ở trên để làm cho nó hoạt động.

Bạn có thể đọc về các tính năng thú vị hơn của DrawableCompat trên các tài liệu ở đây .


1
Tôi cũng phải làm imageView.getBackground()để có được drawable, vì imageView.getDrawable()đã trả về null.
Rock Lee

@RockLee hãy chắc chắn rằng bạn đã sử dụng src trong chế độ xem hình ảnh xml hoặc setImageResource trong mã
orelzion

đây là cách hoàn hảo để đặt màu sắc cho nền hình ảnh
leegor

12

Chức năng mở rộng được đơn giản hóa tốt hơn nhờ ADev

fun ImageView.setTint(@ColorRes colorRes: Int) {
    ImageViewCompat.setImageTintList(this, ColorStateList.valueOf(ContextCompat.getColor(context, colorRes)))
}

Sử dụng:-

imageView.setTint(R.color.tintColor)

Có một cái tương tự cho tông màu văn bản của Nút / TextView không?
nhà phát triển Android

bạn có nghĩa là màu văn bản textview hoặc tint cho textview drawable?
Manohar Reddy

Tôi có nghĩa là "văn bản màu". Màu sắc của văn bản. Nhưng tôi nghĩ nó khá có vấn đề, vì văn bản có một màu cho từng trạng thái ... Sau đó, một lần nữa, làm thế nào nó hoạt động tốt khi tôi đặt màu nhấn ... Lạ .... Có lẽ có thể đặt màu nhấn thành một nút cụ thể (hoặc TextView), theo chương trình?
nhà phát triển Android

11

Nếu màu của bạn có độ trong suốt hex, sử dụng mã dưới đây.

ImageViewCompat.setImageTintMode(imageView, PorterDuff.Mode.SRC_ATOP);
ImageViewCompat.setImageTintList(imageView, ColorStateList.valueOf(Color.parseColor("#80000000")));

Để xóa màu

ImageViewCompat.setImageTintList(imageView, null);

Kiểu "img" là gì
Beyaz

1
@Beyaz imgthuộc loại ImageView.
Sai

10

Đơn giản và một dòng

imageView.setColorFilter(activity.getResources().getColor(R.color.your_color));

9

Vì câu trả lời đầu tiên không hiệu quả với tôi:

//get ImageView
ImageView myImageView = (ImageView) findViewById(R.id.iv);

//colorid is the id of a color defined in values/colors.xml
myImageView.setImageTintList(ColorStateList.valueOf(ContextCompat.getColor(getApplicationContext(), R.color.colorid)));

Điều này dường như chỉ hoạt động trong API 21+, nhưng đối với tôi đó không phải là vấn đề. Bạn có thể sử dụng ImageViewCompat để giải quyết vấn đề đó, tho.

Tôi hy vọng tôi đã giúp bất cứ ai :-)


7

Bắt đầu bằng Lollipop, có một phương pháp được gọi là ImageView#setImageTintList()bạn có thể sử dụng ... lợi thế là nó ColorStateListchỉ thay vì một màu duy nhất, do đó làm cho hình ảnh trở nên rõ ràng.

Trên các thiết bị tiền Lollipop, bạn có thể có hành vi tương tự bằng cách pha màu có thể vẽ và sau đó đặt nó làm ImageViewhình ảnh có thể vẽ được:

ColorStateList csl = AppCompatResources.getColorStateList(context, R.color.my_clr_selector);
Drawable drawable = DrawableCompat.wrap(imageView.getDrawable());
DrawableCompat.setTintList(drawable, csl);
imageView.setImageDrawable(drawable);

6
Random random=new Random;
ImageView imageView = (ImageView) view.findViewById(R.id.imageView);
ColorFilter cf = new PorterDuffColorFilter(Color.rgb(random.nextInt(255), random.nextInt(255), random.nextInt(255)),Mode.OVERLAY);

imageView.setImageResource(R.drawable.ic_bg_box);
imageView.setColorFilter(cf);

6

Để đặt tint cho chế độ xem hình ảnh theo chương trình trong Android

Tôi có hai phương pháp cho Android:

1)

imgView.setColorFilter(context.getResources().getColor(R.color.blue));

2)

 DrawableCompat.setTint(imgView.getDrawable(),
                     ContextCompat.getColor(context, R.color.blue));

Tôi hy vọng tôi đã giúp bất cứ ai :-)


4

Thêm vào câu trả lời của ADev (theo ý kiến ​​của tôi là đúng nhất), vì việc áp dụng rộng rãi của Kotlin và các chức năng mở rộng hữu ích của nó:

fun ImageView.setTint(context: Context, @ColorRes colorId: Int) {
    val color = ContextCompat.getColor(context, colorId)
    val colorStateList = ColorStateList.valueOf(color)
    ImageViewCompat.setImageTintList(this, colorStateList)
}

Tôi nghĩ rằng đây là một chức năng có thể hữu ích trong bất kỳ dự án Android nào!


4

Tôi thấy rằng chúng ta có thể sử dụng bộ chọn màu cho tint attr:

mImageView.setEnabled(true);

Activity_main.xml:

<ImageView
    android:id="@+id/image_view"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:src="@drawable/ic_arrowup"
    android:tint="@color/section_arrowup_color" />

part_arrowup_color.xml:

<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
    <item android:color="@android:color/white" android:state_enabled="true"/>
    <item android:color="@android:color/black" android:state_enabled="false"/>
    <item android:color="@android:color/white"/>
</selector>

Xin chào, Nó không hoạt động cho vector drawables..Bạn có cách giải quyết nào giống nhau không?
Manukumar

@Manukumar Sử dụng app:srcCompatthay vì android:srcvà thêm vectorDrawables.useSupportLibrary = truevào defaultConfigmột phần của tệp build.gradle của bạn. Đã thử nghiệm để hoạt động tốt trên trình giả lập Kitkat.
nhà phát triển Android

3

Không sử dụng PoterDuff.Mode, sử dụng setColorFilter()nó hoạt động cho tất cả.

ImageView imageView = (ImageView) listItem.findViewById(R.id.imageView);
imageView.setColorFilter(getContext().getResources().getColor(R.color.msg_read));

2

Như @milosmns đã nói, bạn nên sử dụng imageView.setColorFilter(getResouces().getColor(R.color.blue),android.graphics.PorterDuff.Mode.MULTIPLY);

API này cần giá trị màu thay vì id tài nguyên màu, đó là nguyên nhân cốt lõi khiến câu lệnh của bạn không hoạt động.


2

Tôi đến trễ trong bữa tiệc nhưng tôi không thấy sự an ủi của mình ở trên. Chúng tôi cũng có thể thiết lập màu sắc qua setImageResource()(minSdkVersion của tôi là 24).

Vì vậy, trước tiên, bạn cần tạo một bộ chọn và lưu nó vào /drawablethư mục tài sản (tôi gọi nó ic_color_white_green_search.xml)

<!-- Focused and not pressed -->
<item android:state_focused="true"
      android:state_pressed="false">

    <bitmap android:src="@drawable/ic_search"
            android:tint="@color/branding_green"/>
</item>

<!-- Focused and pressed -->
<item android:state_focused="true"
      android:state_pressed="true">

    <bitmap android:src="@drawable/ic_search"
            android:tint="@color/branding_green"/>
</item>

<!-- Default -->
<item android:drawable="@drawable/ic_search"/>

Sau đó đặt nó trong mã như thế này:

val icon = itemView.findViewById(R.id.icon) as ImageButton
icon.setImageResource(R.drawable.ic_color_white_green_search)

2

Trong trường hợp bạn muốn đặt bộ chọn thành tông màu của mình:

ImageViewCompat.setImageTintList(iv, getResources().getColorStateList(R.color.app_icon_click_color));

0

Giải pháp Kotlin sử dụng chức năng mở rộng, để thiết lập và hủy đặt màu:

fun ImageView.setTint(@ColorInt color: Int?) {
    if (color == null) {
        ImageViewCompat.setImageTintList(this, null)
        return
    }
    ImageViewCompat.setImageTintMode(this, PorterDuff.Mode.SRC_ATOP)
    ImageViewCompat.setImageTintList(this, ColorStateList.valueOf(color))
}

-4

Không trả lời chính xác nhưng thay thế đơn giản hơn:

  • Đặt một góc nhìn khác lên trên cùng của hình ảnh
  • Thay đổi giá trị alpha của chế độ xem theo cách bạn muốn (theo chương trình) để có được hiệu ứng mong muốn.

Đây là một đoạn cho rằng:

<FrameLayout
    android:layout_width="match_parent"
    android:layout_height="wrap_content">

    <ImageView
        android:layout_width="match_parent"
        android:layout_height="@dimen/height120"
        android:contentDescription="@string/my_description"
        android:scaleType="fitXY"
        android:src="@drawable/my_awesome_image"/>

    <View
        android:layout_width="match_parent"
        android:layout_height="@dimen/height120"
        android:alpha="0.5"
        android:background="@color/my_blue_color"/>
</FrameLayout>

đây là về màu sắc! không phải alpha mà là để minh bạch.
David

Nhưng điều đó kết thúc hoạt động như một tông màu. Bạn nên tự mình thử. Đây chỉ là một cách để nhìn vào mọi thứ.
Shubham Chaudhary

@ShubhamChaudhary Tôi biết điều này là muộn nhưng nếu hình ảnh là gì png. Sau đó, sẽ không thay đổi nền? Ngoài ra Alpha và tint rất khác nhau. Màu giống như thay thế màu, nếu tôi không sai. Không có ý xúc phạm. Chỉ cần cố gắng để giúp đỡ :)
KISHORE_ZE

Điểm hợp lệ. Câu trả lời này đã giúp trong trường hợp của tôi. Hy vọng phù hợp với giày của người khác quá.
Shubham Chaudhary
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.