74

I am using Design Support Library version 23.4.0. I have enabled the gradle flag:

defaultConfig {
    vectorDrawables.useSupportLibrary = true
}

I am using build tools version 23.0.2, but still, I am getting Resources$NotFoundException on KitKat or lower.

It is occurring when I use android:drawableLeft or imageView.setImageResource(R.drawable.drawable_image).

And yes, I am putting this on every activity where I am using drawables

static {
    AppCompatDelegate.setCompatVectorFromResourcesEnabled(true);
}

Is this a bug of the support library?

paulina_glab
  • 2,467
  • 2
  • 16
  • 25
Arka
  • 1,073
  • 1
  • 10
  • 14

14 Answers14

89

It took 3 separate things for me to get this to work using support library 23.4.0:

  1. Add this to build.gradle

    defaultConfig {
        vectorDrawables.useSupportLibrary = true
    }
    
  2. Add the following to onCreate of your Application class

    AppCompatDelegate.setCompatVectorFromResourcesEnabled(true);
    

    (From the reference of this link - "https://stackoverflow.com/a/45582033/10752962")

    In API less then 21,use this line before setContentView();

  3. For all XML views in which you are setting a vector drawable replace

    android:src
    

    with

    app:srcCompat
    

    and in the code replace this:

    imageView.setImageResource(...);
    

    with

    imageView.setImageDrawable(...);
    
Rahul
  • 3,293
  • 2
  • 31
  • 43
Rich Luick
  • 2,354
  • 22
  • 35
  • does this apply even if my activity is based on AppCompatActivity? AppCompatActivity already uses AppCompatDelegate. – Thupten Nov 05 '16 at 20:32
  • Simply use `AppCompatImageView` instead of `ImageView`. Problem solved. No need to keep pngs for lower versions. Even `srcCompat` is not needed. – Harish Gyanani Dec 22 '16 at 05:45
  • I've done steps 1 to 3 (on the 3rd step used `app:srcCompat`). However, I still see an exception `XmlPullParserException: Binary XML file line #4: invalid drawable tag vector`. It looks like the `vector` tag in the XML is not recognized on this KitKat device ? – Someone Somewhere Oct 05 '17 at 14:22
  • `AppCompatDelegate.setCompatVectorFromResourcesEnabled(true);` this was the killer line of code fo me. I had to add that in my application. – shadowsheep Feb 20 '18 at 09:54
  • 2
    why replace `setImageResource` with `seImageDrawable`? – Boy Apr 18 '18 at 04:21
  • 1
    If you use `imageView.setImageResource(...)` then `AppCompatDelegate.setCompatVectorFromResourcesEnabled(true)` is not needed. Tested with 25.3.1 support library. – Eric B. May 15 '18 at 16:51
  • With the new androidX libs, I only had to use "app:srcCompat" to fix the crash. Everything else stayed the same. Only used the XML. For ref. the ress. was: "@drawable/ic_done_white" that only crashed in 4.4. Thx – CaptainCrunch May 28 '22 at 13:41
65

To complement some of the answers here: backward-compatible support for VectorDrawables comes with a price and doesn't work in all cases.

In which cases does it work? I've made this diagram to help (valid for Support Library 23.4.0 to at least 25.1.0).

VectorDrawable cheatsheet

David Ferrand
  • 5,357
  • 1
  • 33
  • 43
  • 1
    It DOESN'T work with `setImageResource` for KitKat (4.4.4) (and lower I guess), only this works https://stackoverflow.com/a/35918375/7767664 – user924 Oct 21 '17 at 19:15
32

Try using:

imageView.setImageDrawable(VectorDrawableCompat.create(getResources(), drawableRes, null));

You don't have to add AppCompatDelegate.setCompatVectorFromResourcesEnabled(true); this way.

Just inflate your vector drawables using VectorDrawableCompat and you're all set.

25

We had the same issue. Vector drawables were not visible on Kitkat. I solved this issue by adding AppCompatDelegate.setCompatVectorFromResourcesEnabled(true); to the onCreate method of Activities.

Before that dont forget to add:

defaultConfig {
    vectorDrawables.useSupportLibrary = true
}

and call setImageResource for the view that you use the vector drawable. My view is ImageButton. I have Android SDK build tools version 23.0.3

Murat
  • 3,084
  • 37
  • 55
  • 3
    My problem is that even `AppCompatDelegate.setCompatVectorFromResourcesEnabled(true);` is not working. The same ResourceNotFound exception. – Arka Jun 05 '16 at 16:29
  • @Arka you may try calling in onCreate method of Activities. – Murat Jun 07 '16 at 11:28
  • 1
    You should be able to add it to the onCreate of you application class. That seems to be working for me. – Rich Luick Jun 16 '16 at 16:14
16

Sorry for being late to the party but this answer may help users who want to enable the flag AppCompatDelegate.setCompatVectorFromResourcesEnabled(true); for all activities.

1. Create a class which extends to Application (android.app.Application)

public class MyApplicationClass extends Application
{
    @Override
    public void onCreate()
    {
        super.onCreate();
    }
}

2. Head over to Manifest.xml and add the following line to your tag

<application
    android:name=".MyApplicationClass"
    android:allowBackup="true"
    android:icon="@mipmap/ic_launcher"
    android:label="@string/app_name"
    android:roundIcon="@mipmap/ic_launcher_round"
    android:supportsRtl="true"
    android:theme="@style/AppTheme">
    ...
</application>

3. Add the following code above onCreate in MyApplicationClass.java

// This flag should be set to true to enable VectorDrawable support for API < 21
static
{
    AppCompatDelegate.setCompatVectorFromResourcesEnabled(true);
}

Complete code for MyApplicationClass.java

import android.app.Application;
import android.support.v7.app.AppCompatDelegate;

/**
* Created by Gaurav Lonkar on 23-Dec-17.
*/

public class MyApplicationClass extends Application
{
    // This flag should be set to true to enable VectorDrawable support for API < 21
    static
    {
        AppCompatDelegate.setCompatVectorFromResourcesEnabled(true);
    }

    @Override
    public void onCreate()
    {
        super.onCreate();
    }
}
zackygaurav
  • 4,369
  • 5
  • 26
  • 40
9
defaultConfig {
  vectorDrawables.useSupportLibrary = true
}

use this in app.gradle

Then use AppCompatDrawableManager to setDrawable and getDrawable. Works for me

Jaap
  • 81,064
  • 34
  • 182
  • 193
emilpmp
  • 1,716
  • 17
  • 32
7

Support for vector drawables in places like android:drawableLeft was disabled in support library 23.3. It was announced on Google+:

we’ve decided to remove the functionality which let you use vector drawables from resources on pre-Lollipop devices due to issues found in the implementation in version 23.2.0/23.2.1. Using app:srcCompat and setImageResource() continues to work.

Links to issues:

However, if you can live with those issues, in 23.4 you can re-enable this functionality using AppCompatDelegate.setCompatVectorFromResourcesEnabled().

If you're curious how this works, the best person to learn from is Chris Banes, who authored this functionality. He explains in detail on his blog.

Marcin Koziński
  • 10,835
  • 3
  • 47
  • 61
5

change

imageView.setImageResource(R.drawable.drawable_image)

to

imageView.setImageDrawable(ContextCompat.getDrawable(getContext(), R.drawable.drawable_image));

if you want to use vectordrawable in xml, use this:

app:srcCompat="@drawable/drawable_image"
jmarkstar
  • 1,335
  • 14
  • 21
  • 2
    Your method setImageDrawable works. But still button drawableLeft not working. – Arka Jun 03 '16 at 13:49
  • This causes crashing on older devices. – Clive Jefferies Apr 07 '17 at 14:34
  • This doesn't work. Use one of the other answers here instead. – Sakiboy May 09 '17 at 00:46
  • you should have this vectorDrawables.useSupportLibrary = true on your build.gradle and this AppCompatDelegate.setCompatVectorFromResourcesEnabled(true); on your onCreate of your Application Class or {AppCompatDelegate.setCompatVectorFromResourcesEnabled(true); } on your activity. Check the question. He added those lines on his code before he ask – jmarkstar May 09 '17 at 15:22
1

I had a similar problem long ago, it did not work by setting

vectorDrawables.useSupportLibrary = true

only worked when I created the "mipmap" folder, and the code used

imageView.setImageResource (R.mipmap.drawable_image)

It has more Info here

Community
  • 1
  • 1
Marco Giovanni
  • 297
  • 7
  • 18
1

API 16 animation
Inflating Drawable's

`VectorDrawable` and `AnimatedVectorDrawable` in this support library can be inflated in this way:

  • Calling static getDrawable() methods:
//This will only inflate a drawable with <vector> as the root element
VectorDrawable.getDrawable(context, R.drawable.ic_arrow_vector);

//This will only inflate a drawable with <animated-vector> as the root element
AnimatedVectorDrawable.getDrawable(context, R.drawable.ic_arrow_to_menu_animated_vector);

// This will inflate any drawable and will auto-fallback to the lollipop implementation on api 21+ devices
ResourcesCompat.getDrawable(context, R.drawable.any_drawable);

If inflating the Drawable in java code, it is recommended to always use ResourcesCompat.getDrawable() as this handles Lollipop fallback when applicable. This allows the system to cache Drawable ConstantState and hence is more efficient.
The library has the following morph (bi-directional) animations :

  • Play-Pause morph animation
  • Play-Stop morph animation
  • Arrow-Hamburger menu morph animation

  • As you can see, I produced the above image on my API 16 phone:
    import com.wnafee.vector.compat.AnimatedVectorDrawable;
    mdrawable = (AnimatedVectorDrawable) AnimatedVectorDrawable.getDrawable(this.getApplicationContext(), R.drawable.consolidated_animated_vector);
    

    Look at the github README for vector-compat here: https://github.com/wnafee/vector-compat
    This will fix your problem (down to API 14) if you merge it with your app module's build.gradle dependencies (usually at the end of file):

    dependencies {
    compile fileTree(dir: 'libs', include: ['*.jar'])
    //Trying to FIX Binary XML file line #2: invalid drawable tag animated-vector
        compile 'com.android.support:appcompat-v7:25.0.0'
        compile 'com.android.support:design:25.0.0'
    //not needed
    //  compile 'com.android.support:support-vector-drawable:25.0.0'
        compile 'com.wnafee:vector-compat:1.0.5'//*******holy grail *******https://github.com/wnafee/vector-compat
    //  Failed to resolve: com.android.support:support-animated-vector-drawable:25.0.0
    //not needed
    //  compile 'com.android.support:support-animated-vector-drawable:25.0.0'
    }
    
    Jon Goodwin
    • 9,053
    • 5
    • 35
    • 54
    1

    Do not put your vectors in drawable-anydpi , old devices does not support that

    put them in drawable

    1

    In my particular case, I had this problem because I was using a drawable selector as the image resource with several vectors in the selector, as in:

    <selector xmlns:android="http://schemas.android.com/apk/res/android">
        <item android:state_selected="true" android:drawable="@drawable/vector_select_blue"/>
        <item android:state_pressed="true" android:drawable="@drawable/vector_select_black"/>
        .
        .
        etc
    </selector>
    

    Yes, pretty bad, but didn't know better at the time.

    So, the right way of doing this is using the tint property in your vector file, as in:

    <vector ..vector properties..
            android:tint="@color/vector_color_selector">
                  <path ..path properties../>
    </vector>
    

    (You can also use the app:tint attribute in the AppCompatImageView)

    And now, your vector_color_selector file should have the colors you want, as in:

    <selector xmlns:android="http://schemas.android.com/apk/res/android">
        <item android:state_selected="true" android:color="@color/blue"/>
        <item android:state_pressed="true" android:color="@color/black"/>
        .
        .
        etc
    </selector>
    

    I hope this helps someone if previous answers didn't work for you. Stating the obvious, but I must say that you still need to set vectorDrawables.useSupportLibrary = true in gradle, use AppCompatImageView and use app:srcCompat or setImageDrawable + AppCompatResources.getDrawable to avoid any troubles with the vector compat library.

    emirua
    • 498
    • 5
    • 14
    0

    Use AppCompatImageView instead of ImageView as said by Harish Gyanani in comments , it works fine with this for me.

    Official docs

    xarlymg89
    • 2,552
    • 2
    • 27
    • 41
    Krishna
    • 65
    • 1
    • 9
    0

    I had the same problem and actually what was missing is I was using app:srcCompat on AppCompatTextView except of AppCompatImageView.

    The way I have found the problematic part:

    My error looks like:

    Fatal Exception: android.content.res.Resources$NotFoundException
    Resource ID #0x7f0700d1
    

    Here are the steps I followed the resource id of the mentioned drawable :

    • APK Analyzer -> classesXXX.dex
    • In this dex file I opened the directory of my apps package name and went to R$drawable file
    • R$drawable -> Show as byte code.
    • Search for ID [0x7f0700d1] (check your own ID)
    • Find the image and check for all the usages (CMD + F7) of the resource
    • Fix

    Hope it will help somebody.

    aleksandrbel
    • 1,422
    • 3
    • 20
    • 38