Android Studio version 2.1, gradle version 2.1.0, please correct me if you spot any misinterpretations :)
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.
I have read several related posts about the changes: 23.2.0 announcement and changes:
As of Android Support Library 23.3.0, support vector drawables can only be loaded via app:srcCompat or setImageResource().
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"/>
Works on Lollipop and above only:
Drawable bg = ContextCompat.getDrawable(a, R.drawable.ic_exit_to_app_24dp); DrawableCompat.setTint(bg, headerTitleColor); exitButton.setImageDrawable(bg);
Attempting this pre-lollipop throws: android.content.res.Resources$NotFoundException: File res/drawable/ic_exit_to_app_24dp.xml from drawable resource ID #0x7f0200bf
Also works on Lollipop and above only
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.
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.
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.
So the situation for 23.3.0 seems to be:
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.
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.
Working on all versions using pngs:
Drawable bg = ContextCompat.getDrawable(a, R.drawable.ic_nav_exit_community); DrawableCompat.setTint(bg, headerTitleColor); exitButton.setImageDrawable(bg);
Addendum:
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);
KIND OF SOLUTION:
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);
A VectorDrawable is a vector graphic defined in an XML file as a set of points, lines, and curves along with its associated color information. The major advantage of using a vector drawable is image scalability.
Tere is need to Change fillColor of a vector drawable in android programmatically, you can edit fill Color of a vector-file in Android programmatically using DrawableCompat. setTint() method which change tint color of whole vector drawable. Here, ImageView is set with drawable vector icon of black color.
first of all you should use VectorDrawableCompat#create
, once you have your Drawable
you have to call DrawableCompat#wrap
:
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);
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With