以编程方式着色支持向量 [英] Programmatically tint a Support Vector

查看:56
本文介绍了以编程方式着色支持向量的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

Android Studio version 2.1, gradle version 2.1.0, please correct me if you spot any misinterpretations :)

我对支持库23.3.0中的支持向量感到困惑.具体来说,我想做的是以编程方式将图像按钮着色,其src定义为可绘制的矢量.据我所知,现在棒棒糖之前是不可能的.

I am confused about support vectors in the support library 23.3.0. Specifically what I would like to do is tint an image button programmatically, whose src is defined is a vector drawable. From what I can tell this is not possible on pre-lollipop now.

我已阅读有关更改的几篇相关文章: 23.2.0公告和更改:

I have read several related posts about the changes: 23.2.0 announcement and changes:

从Android支持库23.3.0开始,支持矢量可绘制对象只能通过app:srcCompat或setImageResource()加载.

As of Android Support Library 23.3.0, support vector drawables can only be loaded via app:srcCompat or setImageResource().

上面的意思是说,矢量xmls只能通过srcCompat或setImageResource()在Lollipop之前使用,因此不能动态着色?

Does the above mean that vector xmls can only be used pre-Lollipop via srcCompat or setImageResource(), and therefore cannot be dynamically tinted?

这是我的基本图片按钮:

Here is my basic image button:

<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"/>

仅适用于棒棒糖及更高版本:

    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

Attempting this pre-lollipop throws: 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);

这会在棒棒糖之前引发相同的错误.

This throws the same error on pre-Lollipop.

但是,如果我删除了vectorDrawables.useSupportLibrary = true,如伊恩·莱克(Ian Lake)在这里指出,目的是拥有构建工具自动为棒棒糖之前的设备生成png,这些png不会在棒棒糖之前着色,所以我回到正题.

However if I remove vectorDrawables.useSupportLibrary = true as pointed out by Ian Lake here, with the intent of having the build tools auto-generate pngs for pre-Lollipop devices, the pngs do not tint on pre-lollipop, so I'm back to square one.

我也尝试过通过srcCompat指定向量并以编程方式检索它,但是即使使用src指定了向量,但我认为我也无法实现,即使它适用于棒棒糖后期代替.

I have also tried specifying the vector via srcCompat and retrieving it programmatically but I don't think I've been able to achieve that, even though it works on post-Lollipop if the vector is specified using src instead.

因此23.3.0的情况似乎是:

So the situation for 23.3.0 seems to be:

  • 棒棒糖后期:srcsrcCompat接受矢量,只有src可以 从视图中检索为可绘制的可绘制对象,以编程方式进行着色. 使用getDrawable可以在代码中引用向量,并且它们 可以着色.

  • Post-Lollipop: src and srcCompat accept vectors, only src can be retrieved from the view as a drawable for tinting programmatically. Referencing vectors in code is possible using getDrawable, and they can be tinted.

棒棒糖前置:srcCompat仅可以接受向量,无法检索 从视图上以编程方式进行着色. setImageResource可以 接受向量,但仅当vectorDrawables.useSupportLibrary = false且着色不起作用时.类似地,在代码中引用向量不是 除非vectorDrawables.useSupportLibrary = false和着色,否则可能 不起作用.

Pre-Lollipop: srcCompat only can accept vectors, cannot be retrieved programmatically from the view for tinting. setImageResource can accept vectors, but only if vectorDrawables.useSupportLibrary = false, and tinting does not work. Similarly referencing vectors in code is not possible unless vectorDrawables.useSupportLibrary = false and tinting does not work.

使用png处理所有版本:

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

附录:

此技术也适用于棒棒糖后期,但像其他棒棒糖之前一样,我可以绘制,但没有着色:

This technique also works on post-Lollipop, but like the others on pre-Lollipop I get the drawable, but no tinting:

    Drawable bg = VectorDrawableCompat.create(a.getResources(), R.drawable.ic_exit_to_app_24dp, null);
    DrawableCompat.setTint(bg, headerTitleColor);
    exitButton.setImageDrawable(bg);

解决方案的类型:

感谢 John的答案到目前为止,我想出的唯一一种支持向量着色的防呆方法是在其上设置滤色器-这意味着DrawableCompat.setTint()函数对于我来说似乎不起作用,如果有问题的可绘制对象是支持向量.我不确定这是不是合法的错误,预期的行为还是我做错了什么!

Thanks to John's answer so far the only fool-proof way I can come up with to tint a support vector is to set a color filter on it - this means the DrawableCompat.setTint() function is seemingly not functional for me if the drawable in question is a support vector. I'm not sure if this is a legit bug, expected behavior or if I'm just doing something wrong!

这是我目前要使用的解决方案:

Here is the solution I'm going with for the moment:

    Drawable bg;
    if(Build.VERSION.SDK_INT < Build.VERSION_CODES.LOLLIPOP) {
        bg = VectorDrawableCompat.create(a.getResources(), R.drawable.ic_exit_to_app_24dp, null);
        exitButton.setColorFilter(headerTitleColor, PorterDuff.Mode.MULTIPLY);
    }
    else {
        bg = ContextCompat.getDrawable(a, R.drawable.ic_exit_to_app_24dp);
        DrawableCompat.setTint(bg, headerTitleColor);
    }
    exitButton.setImageDrawable(bg);

推荐答案

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

first of all you should use VectorDrawableCompat#create, once you have your Drawable you have to call DrawableCompat#wrap:

可能包裹可绘制对象,以便可用于在整个对象上着色 通过此类中的着色方法来设置不同的API级别.

Potentially wrap drawable so that it may be used for tinting across the different API levels, via the tinting methods in this class.

因此您的代码应如下所示:

so your code would look like this:

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

这篇关于以编程方式着色支持向量的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆