简体   繁体   English

支持库 VectorDrawable Resources$NotFoundException

[英]Support library VectorDrawable Resources$NotFoundException

I am using Design Support Library version 23.4.0 .我正在使用设计支持库版本23.4.0 I have enabled the gradle flag:我启用了 gradle 标志:

defaultConfig {
    vectorDrawables.useSupportLibrary = true
}

I am using build tools version 23.0.2 , but still, I am getting Resources$NotFoundException on KitKat or lower.我正在使用构建工具版本23.0.2 ,但仍然在 KitKat 或更低版本上收到Resources$NotFoundException

It is occurring when I use android:drawableLeft or imageView.setImageResource(R.drawable.drawable_image) .当我使用android:drawableLeftimageView.setImageResource(R.drawable.drawable_image)时会发生imageView.setImageResource(R.drawable.drawable_image)

And yes, I am putting this on every activity where I am using drawables是的,我把它放在我使用 drawables 的每个活动中

static {
    AppCompatDelegate.setCompatVectorFromResourcesEnabled(true);
}

Is this a bug of the support library?这是支持库的错误吗?

It took 3 separate things for me to get this to work using support library 23.4.0 :使用支持库 23.4.0使其工作需要 3 件独立的事情:

  1. Add this to build.gradle将此添加到build.gradle

     defaultConfig { vectorDrawables.useSupportLibrary = true }
  2. Add the following to onCreate of your Application class将以下内容添加到Application类的onCreate

     AppCompatDelegate.setCompatVectorFromResourcesEnabled(true);

    (From the reference of this link - " https://stackoverflow.com/a/45582033/10752962 ") (来自此链接的参考 - “ https://stackoverflow.com/a/45582033/10752962 ”)

    In API less then 21 ,use this line before setContentView() ;小于 21 的 API 中,在setContentView()之前使用这一行;

  3. For all XML views in which you are setting a vector drawable replace对于您在其中设置矢量可绘制的所有 XML 视图替换

    android:src

    with

    app:srcCompat

    and in the code replace this:并在代码中替换这个:

     imageView.setImageResource(...);

    with

    imageView.setImageDrawable(...);

To complement some of the answers here: backward-compatible support for VectorDrawables comes with a price and doesn't work in all cases .为了补充这里的一些答案:对 VectorDrawables 的向后兼容支持是有代价的,并非在所有情况下都有效

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).我制作了这张图来提供帮助(对于支持库 23.4.0 到至少 25.1.0 有效)。

VectorDrawable备忘单

Try using:尝试使用:

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

You don't have to add AppCompatDelegate.setCompatVectorFromResourcesEnabled(true);您不必添加AppCompatDelegate.setCompatVectorFromResourcesEnabled(true); this way.这样。

Just inflate your vector drawables using VectorDrawableCompat and you're all set.只需使用 VectorDrawableCompat 扩展您的矢量可绘制对象即可。

We had the same issue.我们有同样的问题。 Vector drawables were not visible on Kitkat.矢量绘图在 Kitkat 上不可见。 I solved this issue by adding AppCompatDelegate.setCompatVectorFromResourcesEnabled(true);我通过添加AppCompatDelegate.setCompatVectorFromResourcesEnabled(true);解决了这个问题AppCompatDelegate.setCompatVectorFromResourcesEnabled(true); to the onCreate method of Activities.到活动的 onCreate 方法。

Before that dont forget to add:在此之前不要忘记添加:

defaultConfig {
    vectorDrawables.useSupportLibrary = true
}

and call setImageResource for the view that you use the vector drawable.并为使用矢量可绘制对象的视图调用 setImageResource。 My view is ImageButton.我的观点是 ImageButton。 I have Android SDK build tools version 23.0.3我有 Android SDK 构建工具版本 23.0.3

Sorry for being late to the party but this answer may help users who want to enable the flag AppCompatDelegate.setCompatVectorFromResourcesEnabled(true);很抱歉迟到了,但这个答案可能会帮助想要启用标志AppCompatDelegate.setCompatVectorFromResourcesEnabled(true); 的用户; for all activities.对于所有活动。

1. Create a class which extends to Application (android.app.Application) 1.创建一个扩展到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 2. 前往 Manifest.xml 并将以下行添加到您的标签中

<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 3.在MyApplicationClass.java的onCreate上面添加如下代码

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

Complete code for MyApplicationClass.java 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();
    }
}
defaultConfig {
  vectorDrawables.useSupportLibrary = true
}

use this in app.gradle在 app.gradle 中使用它

Then use AppCompatDrawableManager to setDrawable and getDrawable.然后使用AppCompatDrawableManager来 setDrawable 和 getDrawable。 Works for me为我工作

Support for vector drawables in places like android:drawableLeft was disabled in support library 23.3.支持库 23.3 中禁用了对android:drawableLeft等地方的矢量可android:drawableLeft支持。 It was announced on Google+ :它在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.由于在 23.2.0/23.2.1 版本的实现中发现了问题,我们决定删除允许您从棒棒糖之前设备上的资源中使用矢量可绘制对象的功能。 Using app:srcCompat and setImageResource() continues to work.使用 app:srcCompat 和 setImageResource() 继续工作。

Links to issues:问题链接:

However, if you can live with those issues, in 23.4 you can re-enable this functionality using AppCompatDelegate.setCompatVectorFromResourcesEnabled() .但是,如果您可以忍受这些问题,那么在 23.4 中您可以使用AppCompatDelegate.setCompatVectorFromResourcesEnabled()重新启用此功能。

If you're curious how this works, the best person to learn from is Chris Banes, who authored this functionality.如果您很好奇它是如何工作的,那么最好向 Chris Banes 学习,他是此功能的作者。 He explains in detail on his blog .在他的博客上详细解释

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:如果要在 xml 中使用 vectordrawable,请使用以下命令:

app:srcCompat="@drawable/drawable_image"

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仅当我创建“mipmap”文件夹时才起作用,并且使用的代码

imageView.setImageResource (R.mipmap.drawable_image)

It has more Info here 这里有更多信息

API 16 动画
Inflating Drawable's充气 Drawable

`VectorDrawable` and `AnimatedVectorDrawable` in this support library can be inflated in this way:这个支持库中的`VectorDrawable``AnimatedVectorDrawable`可以通过这种方式膨胀:

  • Calling static getDrawable() methods:调用静态getDrawable()方法:
//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.如果在 Java 代码中对 Drawable 进行膨胀,建议始终使用ResourcesCompat.getDrawable()因为它在适用时处理 Lollipop 回退。 This allows the system to cache Drawable ConstantState and hence is more efficient.这允许系统缓存 Drawable ConstantState,因此效率更高。
The library has the following morph (bi-directional) animations :该库具有以下变形(双向​​)动画:

  • Play-Pause morph animation播放暂停变形动画
  • Play-Stop morph animation播放停止变形动画
  • Arrow-Hamburger menu morph animation Arrow-Hamburger 菜单变形动画

  • As you can see, I produced the above image on my API 16 phone: 如您所见,我在API 16手机上生成了上图:

     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在此处查看vector-compat的 github READMEhttps : //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):如果您将其与应用程序模块的build.gradle dependencies (通常在文件末尾)合并,这将解决您的问题(直至API 14 ):

     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' }

    Do not put your vectors in drawable-anydpi , old devices does not support that不要把你的向量放在drawable-anydpi ,旧设备不支持

    put them in drawable把它们放在drawable

    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:因此,正确的做法是在矢量文件中使用 tint 属性,如下所示:

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

    (You can also use the app:tint attribute in the AppCompatImageView) (你也可以在 AppCompatImageView 中使用 app:tint 属性)

    And now, your vector_color_selector file should have the colors you want, as in:现在,您的 vector_color_selector 文件应该具有您想要的颜色,如下所示:

    <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.说明显而易见,但我必须说您仍然需要在 gradle 中设置 vectorDrawables.useSupportLibrary = true,使用 AppCompatImageView 并使用 app:srcCompat 或 setImageDrawable + AppCompatResources.getDrawable 来避免矢量兼容库的任何麻烦。

    Use AppCompatImageView instead of ImageView as said by Harish Gyanani in comments , it works fine with this for me.正如 Harish Gyanani 在评论中所说,使用AppCompatImageView而不是ImageView ,它对我来说很好用。

    Official docs 官方文档

    I had the same problem and actually what was missing is I was using app:srcCompat on AppCompatTextView except of AppCompatImageView.我有同样的问题,实际上缺少的是我在 AppCompatTextView 上使用 app:srcCompat,除了 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 :以下是我按照提到的 drawable 的资源 ID 执行的步骤:

    • APK Analyzer -> classesXXX.dex APK 分析器 -> classesXXX.dex
    • In this dex file I opened the directory of my apps package name and went to R$drawable file在这个 dex 文件中,我打开了我的应用程序包名称的目录并转到了 R$drawable 文件
    • R$drawable -> Show as byte code. R$drawable -> 显示为字节码。
    • Search for ID [0x7f0700d1] (check your own ID)搜索 ID [0x7f0700d1](检查您自己的 ID)
    • Find the image and check for all the usages (CMD + F7) of the resource查找图像并检查资源的所有用法(CMD + F7)
    • Fix修复

    Hope it will help somebody.希望它会帮助某人。

    声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

     
    粤ICP备18138465号  © 2020-2024 STACKOOM.COM