Android:Tint使用DrawableCompat

时间:2014-11-06 19:55:18

标签: android compatibility tint

我尝试在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?

8 个答案:

答案 0 :(得分:120)

如果有人需要使用DrawableCompat的着色而不影响其他绘图,请按照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));

答案 1 :(得分:53)

以前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));

答案 2 :(得分:43)

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

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

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

答案 3 :(得分:29)

此处的答案不适用于棒棒糖前设备(SupportLib 23.4.0),但我发布了适用于API 17及更高版本的解决方法:C# code to validate email address

以下代码已经过测试,正在使用API​​ 17,19,21,22,23和N预览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);
    }

答案 4 :(得分:6)

如果您查看DrawableCompat的源代码,您会看到任何版本的&lt; 21 the method does nothing

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

答案 5 :(得分:3)

使用支持库22.1,您可以使用DrawableCompat来设置drawables。

  

DrawableCompat.wrap(Drawable)和setTint(),setTintList()和setTintMode()将起作用:不需要创建和维护单独的drawable只支持多种颜色!

答案 6 :(得分:2)

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

我有一个带有矢量drawable的ImageView用作源drawable(实际上,它是支持向量Drawable from Android支持库23.3)。所以,首先我将它包裹起来:

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

之后,我试着像这样应用色调:

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

没有运气。

我试图在包裹的drawable上调用mutate(),以及在原始drawable上调用{仍然没有运气。呼叫invalidate()的{​​{1}}做了伎俩。

答案 7 :(得分:0)

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

imageView.setImageDrawable(
            ContextCompat.getDrawable(context, R.drawable.somedrawable).apply {
                setTint(ContextCompat.getColor(context, R.color.red))
            })