I'm facing a problem with the new backward compatibility with VectorDrawables. In the Support Library 23.2 was a new feature for backward compatibility with Android VectorDrawables indroduced.
I have an ImageView which is a SelectorDrawable assigned to. This Drawable holds several VectorDrawables so I thought I should use app:srcCompat for compatibility. But it does not work on my Galaxy S2 with android 4.1.2.
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:drawable="@drawable/ic_gps_fixed_24dp"android:state_activated="true" android:state_selected="true"></item>
<item android:drawable="@drawable/ic_gps_not_fixed_24dp" android:state_activated="true" android:state_selected="false"></item>
<item android:drawable="@drawable/ic_gps_not_fixed_24dp" android:state_activated="false" android:state_selected="true"></item>
<item android:drawable="@drawable/ic_gps_off_24dp" android:state_activated="false" android:state_selected="false"></item>
<item android:drawable="@drawable/ic_gps_not_fixed_24dp"></item>
</selector>
All drawables are vector xml files.
When using this SelectorDrawable with srcCompat I get this error:
Caused by: android.content.res.Resources$NotFoundException: File res/drawable/ Caused by: android.content.res.Resources$NotFoundException: File res/drawable/ic_gps_fixed_24dp.xml from drawable resource ID #0x7f0201c1
at android.content.res.Resources.loadDrawable(Resources.java:1951)
at android.content.res.Resources.getDrawable(Resources.java:672)
at android.graphics.drawable.StateListDrawable.inflate(StateListDrawable.java:173)
at android.graphics.drawable.Drawable.createFromXmlInner(Drawable.java:881).xml from drawable resource ID #0x7f0201c1
using android:src is even worse.
If I use one of the vector drawables with app:srcCompat all works fine. So I guess it's a problem with the SelectorDrawable and compatibility.
Has anyone had the same problem and found a solution or is it currently not possible to use VectorDrawables in SelectorDrawables prior to Android 5?
The Quick Facts:
- Compile Target API 23
- Support Libraray 23.3.0
- vectorDrawables.useSupportLibrary = true
- Gradle 2.0
some things have changed since I asked this question so I will answer it myself.
With Support Library 23.4.0 the support for VectorDrawables from Ressources was reenabled: Android Support Library 23.4.0 available now
You can find more information on that in this cast from the Google I/O 2016: What's new in the support library - Google I/O 2016
You need to add this to every Activity where you want to use VectorDrawables on devices below Android 5.0 (Codename Lollipop, API level 21):
So you can now use VectorDrawables in DrawableContainers but it can still cause some issues as mentioned in the sources above so use it with caution.
I did not reenable this feature in my app so far but I will change a lot of my icons to VectorDrawables with my next major release and will then dive deeper into this topic.
Working fine with below changes.
Added in Application class.
app build.gradle inside defaultConfig
As @Jahnold mentioned in the comment to question, support for loading vector drawable from an xml state xml list was removed in 23.3.
However, I found several approaches that can help.
1. Using Tint
The approach is suitable if the drawables from selected state list difference only by colors.
First, create only one vector drawable with tint and white
fillColor
:Second, create color state list
button_tint.xml
placed inres/color
Don't forget add follow lines to
build.gradle
or the approach will not work on old Android versions.2. Hardcode creating
StateListDrawable
The approach is suitable if you use for the state list vector drawables which difference not only a color but also by a figure so you need create several different xml files. Then you can create
StateListDrawable
programmatically as shown in an answer.After watching What's new in the support library - Google I/O 2016 I noticed one useful method in the
AppCompatResources
class. This isAppCompatResources#getColorStateList(Context context, int resId)
. With a help of this method I've implemented selector with vector drawables. Here is my color selector fileicon_selector
:And there is java method that returns tinted drawable:
You can use it like shown below