android - 在旧 Android 版本的图层列表中可绘制矢量

标签 android drawable android-vectordrawable

在较新的 Android 版本上,以下代码:

<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
    <item>
            <shape android:shape="oval">
                <solid android:color="#bdbdbd" />
                <size
                    android:width="60dp"
                    android:height="60dp" />
            </shape>
    </item>
    <item
        android:drawable="@drawable/ic_library_books_black_24dp"
        android:gravity="center"
        android:width="40dp"
        android:height="40dp"
        >
    </item>
</layer-list>

完美地产生了这个:

Vector drawable showing white lists on grey circular background

但是,早期的 Android 版本(API 16 和 19,根据我的测试)根本不喜欢这个,我明白了

E/AndroidRuntime: FATAL EXCEPTION: main
              Process: package.app, PID: 11490
              android.view.InflateException: Binary XML file line #26: Error inflating class ImageView

通货膨胀。我的所有 ImageView 都使用了 app:srcCompat,所以那里没有问题。

标准矢量可绘制对象也可以正常工作,但是当放置在 layer-list 中时,它们会造成困惑。有什么解决方法吗?

最佳答案

图层列表中可绘制矢量的宽度/高度属性仅在 API 23 (Marshmallow) 及更高版本中受支持。如果您在 Android Studio 编辑器中查看您的图层列表可绘制对象,这些属性周围应该有黄色 block ,并警告说这在旧设备上无法可靠运行。

但我认为你可以摆脱警告并达到同样的居中效果:

<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
    <item>
        <shape android:shape="oval">
            <solid android:color="#bdbdbd" />
            <size
                android:width="60dp"
                android:height="60dp" />
        </shape>
    </item>
    <item
        android:drawable="@drawable/ic_library_books_black_24dp"
        android:top="10dp"
        android:bottom="10dp"
        android:left="10dp"
        android:right="10dp">
    </item>
</layer-list>

我在旧的 API 15 手机上对此进行了测试,效果很好。我希望这对你也有用。

更新:

在此答案的先前版本中,我建议不要将 vectorDrawables.useSupportLibrary = true 与图层列表一起使用,因为它会导致崩溃。但是,我最近了解到一种似乎可以修复崩溃的解决方法(同时避免 @android developer 正确提到的胖自动生成的 png 文件)。以下是它正常工作需要做的总结:

请务必在您的 xml 中使用 srcCompat。

    <android.support.v7.widget.AppCompatImageView
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    app:srcCompat="@drawable/layer_list_with_svg" />

将“vectorDrawables.useSupportLibrary”添加到 app/build.gradle

 android {
   defaultConfig {
     vectorDrawables.useSupportLibrary = true
   }
 }

将“setCompatVectorFromResourcesEnabled(true)”添加到 onCreate

protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    AppCompatDelegate.setCompatVectorFromResourcesEnabled(true);
    setContentView(R.layout.activity_main);
}

为什么所有这些都是必要的?

正如一位知识渊博的人向我解释的那样,这与 Android 如何加载兼容的矢量可绘制对象有关。如果您使用 vectorDrawables.useSupportLibrary = true,那么当您使用 app:srcCompat 时, ImageView 将加载 VectorDrawableCompat 可绘制对象。当您的图层列表可绘制对象膨胀时,它无法弄清楚如何创建那些引用的矢量可绘制对象。但是,如果您打开 setCompatVectorFromResourcesEnabled 它将尝试在比 ImageView 及其 app:srcCompat 属性低得多的级别 Hook 矢量可绘制对象,因此它能够弄清楚如何加载图层列表中引用的矢量绘图。

关于android - 在旧 Android 版本的图层列表中可绘制矢量,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42885410/

相关文章:

android - 在 Android < API 级别 11 中旋转 ImageView

java - 如何以编程方式将系统 UI 设置为深色模式(而非应用程序)?

java - Android 的 Java 中的 PerformSelectorOnMainThread 等效项

java - 在单元测试中使用 Intent 类

android - 使用加速度计机器人的运动方向不起作用

android - 怎么把toolbar的logo放在右边?

android - 如何在android中按名称访问可绘制资源

android - 我可以像使用 9 补丁一样使用矢量可绘制对象吗?

android - 在运行时从 SVG 文件创建 VectorDrawable

android - 什么时候使用 VectorDrawable?