如何在安卓中编程设置图像视图的色调?

576

需要为图像视图设置色调... 我按以下方式使用它:

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

但这并不改变...


17
你可能在使用整数资源id时出现了错误,应该尝试将R.color.blue转换为getResources().getColor(R.color.blue),这样可以得到整数颜色值。请注意,这不会改变原有含义,只是让语言更加通俗易懂。 - milosmns
Drawable drawable = ... ; drawable.setColorFilter(ContextCompat.getColor(context, R.color.white), PorterDuff.Mode.DST);
imageView.setImageDrawable(drawable); // 这里可以使用任何颜色
- flame3
30个回答

1258

更新:
@ADev在他的回答这里中提供了一个更新的解决方案,但他的解决方案需要更新的支持库 - 25.4.0或以上。


您可以通过以下代码轻松更改色调:

imageView.setColorFilter(Color.argb(255, 255, 255, 255)); // 白色色调

如果你想要彩色色调,则使用

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

对于矢量图形

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

14
在XML中,android:tint="@color/blue"表示对指定控件进行蓝色着色。 - Luis
9
android:tint 可以在所有 Android 版本上使用。也许你指的是 drawableTint - finstas
22
PorterDuff.Mode.MULTIPLY在我的情况下无法工作,我使用了PorterDuff.Mode.SRC_IN并且它有效。 - Mohamed Nageh
1
@ADev 当然,但你在回答中没有恰当地提到你的解决方案是新的,并且需要更新的支持库25.4.0及以上版本,因为在低版本的支持库中,这个类是不可用的,所以没有人能够找到它!!!顺便说一句,我编辑了答案:)祝好运... - Hardik
显示剩余13条评论

399

大多数答案都提到使用setColorFilter,这不是最初的问题所在。

@Tad用户的答案指向正确方向,但只适用于API 21+。

要在所有Android版本上设置色调,请使用ImageViewCompat

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

请注意,yourTint 在这种情况下必须是“颜色 int”。 如果您有像R.color.blue这样的颜色资源,则需要先加载颜色 int:

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

13
应该被接受的答案。请注意,它仅适用于使用AppCompat主题的xml ImageView实例或AppCompatImageView子类。 - Louis CAD
1
@ADev 感谢您的解决方案,但该问题是在2013年提出的,ImageViewCompat和AppCompatImageView是在2017年6月发布的v4支持库25.4.0中推出的,而在2016年12月发布的25.1.0版本中也有这两个类。 :) - Hardik
1
@ADev 当然,但你在你的回答中没有正确提及,你的解决方案是新的,需要较新的支持库 25.4.0 及以上版本,因为在较低版本的支持库中,这个类是不可用的,所以没有人能找到它!!!顺便说一下,我已经编辑了答案 :) 祝你有个好日子... - Hardik

77

这对我起作用了

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

3
对我也有效,不需要第二个参数..它也可以这样写 mImageView.setColorFilter(getContext().getResources().getColor(R.color.green_500)); - Biskrem Muhammad
1
点赞并且没有第二个参数时,它像魅力一样工作。谢谢 @toobsco42 - Ravi Vaniya

39

@Hardik 的回答是正确的。你代码中的另一个错误是当引用 XML 定义的颜色时。你只向 setColorFilter 方法传递了 ID,而应该使用该 ID 来定位颜色资源,并将 资源 传递给 setColorFilter 方法。下面是重写后的原始代码。

如果此行代码在您的 Activity 中:

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

否则,您需要引用您的主活动:

Activity main = ...
imageView.setColorFilter(main.getResources().getColor(R.color.blue), android.graphics.PorterDuff.Mode.MULTIPLY);
请注意,其他类型的资源(如整数、布尔值、尺寸等)也是如此。除了字符串之外,您可以直接在Activity中使用getString(),而无需先调用getResources()(不要问我为什么)。否则,您的代码看起来很不错。(虽然我没有太深入地研究setColorFilter方法...)

33

多亏了ADev,现在有更好的简化扩展函数了。

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

使用方法:

imageView.setTint(R.color.tintColor)

Button/TextView的文本色调是否有类似的功能? - android developer
你是指TextView的文本颜色还是TextView Drawable的着色? - Manohar
我的意思是“文本色调”。文本的颜色。但我认为这很有问题,因为每个状态的文本都有一种颜色...再说了,当我设置强调颜色时它为什么能正常工作呢...奇怪....也许可以通过编程将强调颜色设置为特定的按钮(或TextView)吗? - android developer

25

在我尝试了所有方法且它们对我都无效后。

我通过使用另一个PortDuff.MODE获得了解决方案。

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

25

如果您的颜色具有十六进制透明度,请使用下面的代码。

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

去除色调

ImageViewCompat.setImageTintList(imageView, null);

"img"的类型是什么? - Ucdemir
1
@Beyaz img 是 ImageView 类型。 - Sai

17

简洁明了,一目了然

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

16

从Lollipop开始,BitmapDrawables也有了一个tint方法,可以与新的Palette类一起使用:

public void setTintList(ColorStateList tint)

public void setTintMode(PorterDuff.Mode tintMode)

在旧版本的Android上,现在可以使用DrawableCompat库。


2
实际上,支持库是支持这个的。请看我的答案:https://dev59.com/dmIj5IYBdhLWcg3wkl2U#34479043。 - android developer

14

试试这个。它应该适用于支持库支持的所有Android版本:

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;
}
你可以使用以上任何一种来使其工作。
你可以在文档中阅读有关DrawableCompat更多有趣功能的信息,这里

1
我还不得不执行imageView.getBackground()来获取可绘制对象,因为imageView.getDrawable()返回的是null。 - Rock Lee
@RockLee 确保你在 ImageView 的 XML 中使用了 src 或在代码中使用了 setImageResource。 - orelzion
这是为ImageView背景设置色调颜色的完美方法。 - leegor

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接