以编程方式为支持向量着色

时间:2016-04-27 18:10:02

标签: android android-appcompat android-vectordrawable

Android Studio 2.1版,gradle版本2.1.0,如果发现任何误解,请纠正我:)

我对支持库23.3.0中的支持向量感到困惑。具体来说,我想要的是以编程方式设置图像按钮,其src被定义为矢量drawable。据我所知,现在棒棒糖前不可能。

我已阅读有关这些变化的几篇相关帖子: 23.2.0 announcement and changes

  

从Android支持库23.3.0开始,支持向量drawable只能通过app:srcCompat或setImageResource()加载。

上述是否意味着矢量xmls只能通过srcCompat或setImageResource()在Lollipop之前使用,因此无法动态着色

这是我的基本图像按钮:

<ImageButton
    android:id="@+id/nav_header_exit_community_button"
    android:layout_width="48dp"
    android:layout_height="48dp"
    android:layout_alignParentTop="true"
    android:layout_alignParentRight="true"
    android:background="@null"/>

只适用于Lollipop及以上版本:

    Drawable bg = ContextCompat.getDrawable(a, R.drawable.ic_exit_to_app_24dp);
    DrawableCompat.setTint(bg, headerTitleColor);
    exitButton.setImageDrawable(bg);

尝试这个前棒棒糖投掷: android.content.res.Resources$NotFoundException: File res/drawable/ic_exit_to_app_24dp.xml from drawable resource ID #0x7f0200bf

也适用于棒棒糖及以上

    Drawable bg = ContextCompat.getDrawable(a, R.drawable.ic_exit_to_app_24dp);
    DrawableCompat.setTint(bg, headerTitleColor);
    exitButton.setImageResource(R.drawable.ic_exit_to_app_24dp);

这会给前Lollipop带来同样的错误。

但是,如果我按照by Ian Lake here删除vectorDrawables.useSupportLibrary = true,目的是让构建工具为Lollipop前设备自动生成png,那么 pngs不会预先显示棒棒糖,所以我回到原点。

我也尝试通过srcCompat指定向量并以编程方式检索它,但我认为我无法实现这一点,即使它在Lollipop后工作,如果使用{指定了向量{1}}而不是。

所以23.3.0的情况似乎是:

  • 棒棒糖后:srcsrc接受向量,只有srcCompat可以 从视图中检索为可绘制的,用于以编程方式进行着色。 使用getDrawable可以在代码中引用向量 可以着色。

  • Pre-Lollipop:srcCompat只能接受向量,无法检索 从编程的角度来看。 src可以 接受矢量,但仅限于setImageResource,并且着色不起作用。类似地,代码中的引用向量不是 可能除非vectorDrawables.useSupportLibrary = false和着色 不起作用。

使用pngs处理所有版本:

vectorDrawables.useSupportLibrary = false

附录:

这项技术也适用于棒棒糖后期,但与前棒棒糖上的其他技术一样,我得到了可绘制的,但没有着色:

   Drawable bg = ContextCompat.getDrawable(a, R.drawable.ic_nav_exit_community);
   DrawableCompat.setTint(bg, headerTitleColor);
   exitButton.setImageDrawable(bg);

解决方案:

感谢John's回答到目前为止我唯一可以提出的用于设置支持向量的简单方法是在其上设置一个颜色过滤器 - 这意味着 Drawable bg = VectorDrawableCompat.create(a.getResources(), R.drawable.ic_exit_to_app_24dp, null); DrawableCompat.setTint(bg, headerTitleColor); exitButton.setImageDrawable(bg); 函数似乎不是如果所涉及的可绘制是支持向量,则对我有用。我不确定这是一个合法的错误,预期的行为还是我只是做错了什么!

这是我现在要解决的问题:

DrawableCompat.setTint()

3 个答案:

答案 0 :(得分:30)

首先,您应该使用VectorDrawableCompat#create,一旦您拥有Drawable,就必须致电DrawableCompat#wrap

  

潜在地包裹可绘制的,以便它可以用于着色   不同的API级别,通过此类中的着色方法。

所以你的代码看起来像这样:

ImageView iv = ....
Drawable d = VectorDrawableCompat.create(getResources(), R.drawable.ic_exit_to_app_24dp, null);
d = DrawableCompat.wrap(d);
DrawableCompat.setTint(d, headerTitleColor);
iv.setImageDrawable(d);

答案 1 :(得分:5)

您可以使用ImageView的setColorFilter方法:

imageView.setColorFilter(headerTitleColor, android.graphics.PorterDuff.Mode.MULTIPLY);

答案 2 :(得分:0)

Kotlin的另一种便捷解决方案:

fun Context.drawableWithColor(@DrawableRes drawableRes: Int, @ColorInt color: Int): Drawable? {
    val pic = ContextCompat.getDrawable(this, drawableRes)
    pic?.setColorFilter(color, PorterDuff.Mode.SRC_IN)
    return pic
}

使用非常简单:

val drawable = context.drawableWithColor(R.drawable.your_awesome_drawable, Color.BLUE)