android - 在 Lollipop 崩溃前使用 android vector Drawables

标签 android vector android-support-library android-drawable android-compatibility

我在 Lollipop 之前的 Android 中使用矢量可绘制对象,这些是我的一些库和工具版本:

  • Android Studio : 2.0
  • Android Gradle 插件:2.0.0
  • 构建工具:23.0.2
  • Android 支持库:23.3.0

我在我的应用级别 Build.Gradle

中添加了这个属性
android {  
  defaultConfig {  
    vectorDrawables.useSupportLibrary = true  
   }  
}

还值得一提的是,我使用了一个额外的可绘制对象,例如 Android 官方博客 (link here) 中所述的 LayerDrawable(layer_list) 来为 app:srcCompat

<level-list xmlns:android="http://schemas.android.com/apk/res/android">
    <item android:drawable="@drawable/search"/>
</level-list>

You’ll find directly referencing vector drawables outside of app:srcCompat will fail prior to Lollipop. However, AppCompat does support loading vector drawables when they are referenced in another drawable container such as a StateListDrawable, InsetDrawable, LayerDrawable, LevelListDrawable, and RotateDrawable. By using this indirection, you can use vector drawables in cases such as TextView’s android:drawableLeft attribute, which wouldn’t normally be able to support vector drawables.

当我使用 app:srcCompat 时一切正常,但是当我使用时:

android:background
android:drawableLeft
android:drawableRight
android:drawableTop
android:drawableBottom

在 Lollipop 之前的 ImageViewImageButtonTextViewEditText 上,它会抛出一个期望:

Caused by: android.content.res.Resources$NotFoundException: File res/drawable/search_toggle.xml from drawable resource ID #0x7f0200a9

最佳答案

最新更新 - 2019 年 6 月

支持库自原始答案以来发生了一些变化。现在,即使是 Gradle 的 Android 插件也能够在构建时自动生成 PNG。因此,以下是目前应该可以使用的两种新方法。您可以找到更多信息here:

PNG 生成

Gradle 可以在构建时自动从您的 Assets 创建 PNG 图像。但是,在这种方法中,并非所有 xml 元素都受支持。这个解决方案很方便,因为您不需要更改代码或 build.gradle 中的任何内容。只需确保您使用的是 Android Plugin 1.5.0 或更高版本Android Studio 2.2 或更高版本

我在我的应用程序中使用了这个解决方案并且工作正常。不需要额外的 build.gradle 标志。没有黑客是必要的。如果你去 /build/generated/res/pngs/... 你可以看到所有生成的 PNG。

所以,如果你有一些简单的图标(因为不是所有的 xml 元素都受支持),这个解决方案可能对你有用。只需更新您的 Android Studio 和 Gradle 的 Android 插件即可。

支持库

这可能是适合您的解决方案。如果您来到这里,则意味着您的 Android Studio 不会自动生成 PNG。所以,你的应用程序崩溃了。

或者,您可能根本不希望 Android Studio 生成任何 PNG。

与支持 XML 元素子集的“自动 PNG 生成”不同,此解决方案支持所有 xml 标记。所以,你完全支持你的矢量绘图。

您必须首先更新您的 build.gradle 以支持它:

android {
  defaultConfig {
    // This flag will also prevents Android Studio from generating PNGs automatically
    vectorDrawables.useSupportLibrary = true
  }
}

dependencies {
  // Use this for Support Library
  implementation 'com.android.support:appcompat-v7:23.2.0' // OR HIGHER

  // Use this for AndroidX
  implementation 'androidx.appcompat:appcompat:1.1.0' // OR HIGHER
}

然后,在加载 VectorDrawables 时使用 app:srcCompat 而不是 android:src。不要忘记这一点。

对于TextView,如果你使用的是androidx版本的Support Library,你可以使用app:drawableLeftCompat(或者右,上, 底部) 而不是 app:drawableLeft

如果是 CheckBox/RadioButton,请使用 app:buttonCompat 而不是 android:button

如果您没有使用 androidx 版本的支持库并且您的 minSdkVersion17 或更高版本或使用按钮,您可以尝试通过编程方式设置

Drawable icon = AppCompatResources.getDrawable(context, <drawable_id>);
textView.setCompoundDrawablesWithIntrinsicBounds(<leftIcon>,<topIcon>,<rightIcon>,<bottomIcon>);

更新 - 2016 年 7 月

他们在
中重新启用了 VectorDrawable Android Support Library 23.4.0

For AppCompat users, we’ve added an opt-in API to re-enable support Vector Drawables from resources (the behavior found in 23.2) via AppCompatDelegate.setCompatVectorFromResourcesEnabled(true) - keep in mind that this still can cause issues with memory usage and problems updating Configuration instances, hence why it is disabled by default.

也许build.gradle 设置现在已过时,您只需要在适当的 Activity 中启用它(但是,需要测试)。

现在,要启用它,您必须:

public class MainActivity extends AppCompatActivity {
    static {
        AppCompatDelegate.setCompatVectorFromResourcesEnabled(true);
    }

    ...
}

原始答案 - 2016 年 4 月

我认为这是因为支持向量在最新的库版本中被禁用:23.3.0

据此POST :

For AppCompat users, 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 (ISSUE 205236). Using app:srcCompat and setImageResource() continues to work.

如果您访问问题 ISSUE 205236 , 看来他们会在未来启用,但内存问题不会很快修复:

In the next release I've added an opt-in API where you can re-enable the VectorDrawable support which was removed. It comes with the same caveats as before though (memory usage and problems with Configuration updating).

我遇到了类似的问题。因此,就我而言,我将所有使用可绘制矢量的图标从资源中再次恢复为 PNG 图像(因为即使在他们提供再次启用它的选项后,内存问题仍会继续发生)。

我不确定这是否是最佳选择,但在我看来,它修复了所有崩溃问题。

关于android - 在 Lollipop 崩溃前使用 android vector Drawables,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36867298/

相关文章:

android - '_Smi' 不是类型 'bool' 的子类型 - Flutter MethodChannel

java - Android PopupMenu 在recycleview 中不起作用?

Android:使用 android.support.v7.widget.Toolbar 的 RuntimeException 和 InflateException

android - Api 28 类是从 androidx 的支持库中调用的

java - 包 android.support.v4.app 不存在

java - SimpleDateFormat 返回不同的结果

android - Python框架选择

c - 如何将指针传递给 C 中的 vector 扩展

c++ - 计算成员值时 vector 的奇怪问题

c++ - 使用 fstream 读取带有 float 的 vector