以编程方式着色支持向量 [英] Programmatically tint a Support Vector
问题描述
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:
-
棒棒糖后期:
src
和srcCompat
接受矢量,只有src
可以 从视图中检索为可绘制的可绘制对象,以编程方式进行着色. 使用getDrawable可以在代码中引用向量,并且它们 可以着色.
Post-Lollipop:
src
andsrcCompat
accept vectors, onlysrc
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屋!