52

我正在尝试在 Android API 级别 21 之前为图像着色。我已成功使用以下方法着色项目:

<android:tint="@color/red"/>

但是,我似乎无法通过 ImageView 上的代码弄清楚如何做到这一点:

Drawable iconDrawable = this.mContext.getResources().getDrawable(R.drawable.somedrawable);
DrawableCompat.setTint(iconDrawable, this.mContext.getResources().getColor(R.color.red));
imageView.setImageDrawable(iconDrawable);

我试过设置 TintMode 但这似乎没有什么不同。我是否错误地使用了 v4 兼容类 DrawableCompat?

4

8 回答 8

127

如果有人需要在DrawableCompat不影响其他可绘制对象的情况下使用 's tinting,请按照以下方式操作mutate()

Drawable drawable = getResources().getDrawable(R.drawable.some_drawable);
Drawable wrappedDrawable = DrawableCompat.wrap(drawable);
wrappedDrawable = wrappedDrawable.mutate();
DrawableCompat.setTint(wrappedDrawable, getResources().getColor(R.color.white));

可以简化为:

Drawable drawable = getResources().getDrawable(R.drawable.some_drawable);
drawable = DrawableCompat.wrap(drawable);
DrawableCompat.setTint(drawable.mutate(), getResources().getColor(R.color.white));
于 2015-06-19T00:25:26.740 回答
55

以前的着色不受DrawableCompat. 从支持库 22.1 开始,您可以这样做,但您需要这样做:

Drawable normalDrawable = getResources().getDrawable(R.drawable.drawable_to_tint);
Drawable wrapDrawable = DrawableCompat.wrap(normalDrawable);
DrawableCompat.setTint(wrapDrawable, getResources().getColor(R.color.colorPrimaryLight));
于 2015-04-27T08:27:39.763 回答
49

跨平台着色的最简单方法(如果您不需要 ColorStateList)是:

drawable.mutate().setColorFilter(color, PorterDuff.Mode.SRC_IN);

不要忘记在应用过滤器之前改变 Drawable。

于 2015-06-17T00:40:27.450 回答
30

这里的答案不适用于棒棒糖之前的设备(SupportLib 23.4.0),但我发布了一个适用于 API 17 及更高版本的解决方法:https ://stackoverflow.com/a/37434219/2170109

以下代码已经过测试,正在 API 17、19、21、22、23 和 N Preview 3 上运行:

    // https://stackoverflow.com/a/30928051/2170109
    Drawable drawable = DrawableCompat.wrap(ContextCompat.getDrawable(context, R.drawable.vector));
    image.setImageDrawable(drawable);

    /*
     * need to use the filter | https://stackoverflow.com/a/30880522/2170109
     * (even if compat should use it for pre-API21-devices | https://stackoverflow.com/a/27812472/2170109)
     */
    int color = ContextCompat.getColor(context, R.color.yourcolor);
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
        DrawableCompat.setTint(drawable, color);

    } else {
        drawable.mutate().setColorFilter(color, PorterDuff.Mode.SRC_IN);
    }
于 2016-05-25T10:24:57.047 回答
6

如果您查看 DrawableCompat 的源代码,您会发现对于任何 <21 的版本,该方法什么都不做

DrawableCompat 的想法似乎根本不会在旧版本上崩溃,而不是实际提供该功能。

于 2015-01-07T04:38:29.443 回答
3

使用支持库 22.1,您可以使用 DrawableCompat 为可绘制对象着色。

DrawableCompat.wrap(Drawable) 和 setTint()、setTintList() 和 setTintMode() 将正常工作:无需创建和维护单独的可绘制对象,仅支持多种颜色!

于 2015-04-22T06:55:40.030 回答
3

我将在这里分享我的解决方案,因为它可能会为某人节省一些时间。

我有一个ImageViewwith vector drawable 用作它的源 drawable(实际上,它是来自Android Support Library 23.3 的 Support Vector Drawable)。所以,首先我把它包装成这样:

mImageView.setImageDrawable(DrawableCompat.wrap(mImageView.getDrawable()));

之后,我尝试像这样对其应用色调:

DrawableCompat.setTint(
    mImageView.getDrawable(),
    getResources().getColor(R.color.main_color)
);

没运气。

我试图调用mutate()包装的可绘制对象以及原始可绘制对象 - 仍然没有运气。invalidate()叫了就mImageView成功了。

于 2016-03-24T17:08:55.217 回答
0

为视图设置 tint 和 drawable 并使其向后兼容,同时使用 kotlin 支持当前的上下文主题,而不检查当前的 SDK 版本并避免不推荐使用的方法:

imageView.setImageDrawable(
            ContextCompat.getDrawable(context, R.drawable.somedrawable).apply {
                setTint(ContextCompat.getColor(context, R.color.red))
            })
于 2020-02-01T14:03:13.387 回答