在较新的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>
完美地产生了这个:
然而,早期的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
通货膨胀后。我已将app:srcCompat
用于我的所有ImageView,因此没有任何问题。
标准矢量Drawables也可以正常工作,但当放在layer-list
时它们会造成混乱。有没有解决方法?
答案 0 :(得分:21)
图层列表中矢量绘图的宽度/高度属性仅在API 23(Marshmallow)及更高版本中受支持。如果你在Android Studio编辑器中查看你的图层列表drawable,这些属性应该在它们周围有黄色块,并警告说这在旧设备上不能可靠地工作。
但我认为你可以摆脱警告并达到同样的中心效果:
<?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开发人员正确提到的胖的自动生成的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如何加载compat矢量drawables有关。如果您使用vectorDrawables.useSupportLibrary = true
,那么当您使用VectorDrawableCompat
时,图片视图会加载app:srcCompat
个drawable。当你的图层列表drawable膨胀时,它无法弄清楚如何创建那些引用的矢量drawables。但是如果你打开setCompatVectorFromResourcesEnabled
,它会尝试将矢量可绘制加载挂钩到比图像视图及其app:srcCompat
属性低得多的水平,这样它就可以弄清楚如何加载矢量drawables在图层列表中引用。
答案 1 :(得分:8)
这个答案借鉴了Chris Banes撰写的文章AppCompat - Age of the Vectors(他在支持库中工作)。对于这个问题,我们特别关注标题为 The magic&#39; magic&#39;方式强>
您遇到的崩溃是因为支持库默认情况下只允许某些方式使用VectorDrawables,而layer-list不是其中之一。
您可以在活动顶部添加一个特定的代码块,以启用其他VectorDrawable
用途,例如<layer-list>
:
static {
AppCompatDelegate.setCompatVectorFromResourcesEnabled(true);
}
注意:链接的文章在此方法名称中包含拼写错误,使用&#34; FromSources&#34;,它应该是&#34; FromResources&#34;如上所示。
您需要将此添加到您要使用此类drawable的每个Activity,或者将其包含在您的其他Activities扩展的BaseActivity类中。
根据这篇文章,这应该意味着现在可以使用以下内容:
DrawableContainers,它引用其他只包含矢量资源的drawables资源。
... StateListDrawable ... InsetDrawable,LayerDrawable,LevelListDrawable和RotateDrawable。
应该注意的是,这个方法非常适用于“可能”这个词,这个可能正常工作,并且默认情况下没有启用,所以要注意并检查它真的为你工作!
现在,这个问题实际上是另一个方面,其他用户 Selim Ajimi 和 Rapunzel Van Winkle 可以在答案中解决这个问题。 <layer-list>
在API之间有一些不同的行为,特别是{23}中仅支持width
的{{1}}和height
属性。这不是导致崩溃的原因,也不会导致您的应用程序崩溃,但这意味着一旦您的映像在早期的API中运行,您的映像就不会像预期的那样。
Rapunzel Van Winkle的建议确实似乎是在API中正确定位drawable的好方法(在API 16和24上测试):
<item>
答案 2 :(得分:1)
<?xml version="1.0" encoding="utf-8"?>
<layer-list
xmlns:android="http://schemas.android.com/apk/res/android" >
<item
android:drawable="@[package:]drawable/drawable_resource"
android:id="@[+][package:]id/resource_name"
android:top="dimension"
android:right="dimension"
android:bottom="dimension"
android:left="dimension" />
</layer-list>
正如您所看到的,here没有宽度/高度属性......
您可以将Bitmap追加到项目我认为这是最佳解决方案
答案 3 :(得分:1)
对于旧Android版本,对VectorDrawble的支持为quite limited,假设您使用vectorDrawables.useSupportLibrary = true
:
您可以将VectorDrawableCompat用于API级别7和 运行Android 5.0的所有设备上的AnimatedVectorDrawableCompat(API 等级11)及更高。 Android加载drawables的方式,而不是每个地方 接受可绘制ID,例如在XML文件中,支持加载 矢量drawables。 android.support.v7.appcompat包中添加了一个 一些功能,使其易于使用矢量drawables。首先, 当您使用带有ImageView或的android.support.v7.appcompat包时 使用像ImageButton和FloatingActionButton这样的子类,你可以 使用新的app:srcCompat属性来引用矢量drawables as 以及android:src
可用的任何其他drawable
即使在代码中,您也是有限的:
要在运行时更改drawable,可以使用setImageResource() 方法和以前一样。使用AppCompat和app:srcCompat是最多的 将矢量绘图集成到您的应用程序中的万无一失的方法。
你能做什么?
几种可能的解决方案:
具有您在LayerDrawable中使用的VectorDrawable的替代drawable。例如,将它放在res / drawable-xxhdpi中,将VectorDrawable放入res / drawable-anydpi。
不要使用vectorDrawables.useSupportLibrary = true
,直到您的应用程序具有能够使用VectorDrawable的minSdk。这将起作用,因为IDE将为您生成PNG文件。
以编程方式创建layerList(示例here),并且为了放置VectorDrawable,请使用AppCompatResources.getDrawable
。除了放置VectorDrawable之外,您也可以使用XML。
此功能默认为禁用,因为启用它可能会导致问题 内存使用情况以及更新配置实例时出现问题。如果 您手动更新配置,然后您可能不想要 启用此功能。 您已收到警告。