我在Lollipop 之前的android 中使用了vector drawables,这些是我的一些库和工具版本:
我在应用级Build.Gradle
android {
defaultConfig {
vectorDrawables.useSupportLibrary = true
}
}
还值得一提的是,我使用了一个额外的drawable,如Android官方博客(link here)中所述的LayerDrawable(layer_list),用于设置app:srcCompat
之外的矢量绘图的drawables
<level-list xmlns:android="http://schemas.android.com/apk/res/android">
<item android:drawable="@drawable/search"/>
</level-list>
你会发现直接引用外面的矢量绘图 app:srcCompat将在Lollipop之前失败。但是,AppCompat确实如此 支持在另一个引用它们时加载矢量drawable 可绘制容器,如StateListDrawable,InsetDrawable, LayerDrawable,LevelListDrawable和RotateDrawable。通过使用这个 间接,您可以在TextView的情况下使用矢量drawable android:drawableLeft属性,通常不能 支持矢量绘图。
当我使用app:srcCompat
时,一切正常,但是当我使用时:
android:background
android:drawableLeft
android:drawableRight
android:drawableTop
android:drawableBottom
在Lollipop之前的ImageView
,ImageButton
,TextView
或EditText
上,它会引发预期:
Caused by: android.content.res.Resources$NotFoundException: File res/drawable/search_toggle.xml from drawable resource ID #0x7f0200a9
答案 0 :(得分:65)
我认为这是因为支持向量在最新的库版本中被禁用:23.3.0
根据POST:
对于AppCompat用户,由于版本23.2.0 / 23.2.1 (ISSUE 205236)中的实现中发现的问题,我们决定删除允许您使用Lollipop前设备上的资源使用矢量绘图的功能。使用app:srcCompat和setImageResource()继续工作。
如果您访问问题ISSUE 205236,它们似乎将来会启用,但内存问题不会很快解决:
在下一个版本中,我添加了一个选择加入API,您可以在其中重新启用已删除的VectorDrawable支持。它具有与以前相同的警告(内存使用和配置更新问题)。
我有类似的问题。因此,在我的情况下,我将所有使用矢量绘制的图标从资源恢复为PNG图像(因为即使在他们提供再次启用它的选项后,内存问题也会继续发生)。
我不确定这是否是最好的选择,但它确定了我认为的所有崩溃。
<强>更新强>
他们重新启用了VectorDrawable Android Support Library 23.4.0
对于AppCompat用户,我们添加了选择加入 API,以便通过AppCompatDelegate.setCompatVectorFromResourcesEnabled从资源(23.2中的行为)重新启用支持Vector Drawables (true) - 请记住,这仍然会导致内存使用问题和更新配置实例的问题,因此默认情况下会禁用它。
可能,build.gradle
设置现已过时,您只需要在适当的活动中启用它(但需要测试)。
现在,要启用它,您必须执行以下操作:
public class MainActivity extends AppCompatActivity {
static {
AppCompatDelegate.setCompatVectorFromResourcesEnabled(true);
}
...
}
答案 1 :(得分:56)
我遇到了同样的问题。 但做了很多R&amp; D我得到了答案。
对于Imageview和ImageButton使用,app:srcCompat="@drawable/...."
对于像Button,Textview这样的其他视图,而不是在XML中使用"drawableLeft/right..."
,请将programable规定为:
button.setCompoundDrawablesWithIntrinsicBounds(AppCompatResources.getDrawable(mContext,R.drawable.ic_share_brown_18dp), null, null, null);
使用“AppCompatResources”获取drawable。
答案 2 :(得分:47)
详细说明其他very good answers,这里有a diagram可以帮助您。如果您的支持库从23.4.0到至少25.1.0,则有效。
答案 3 :(得分:36)
Guillherme P 的答案非常棒。只是为了做一个小的改进,你不需要在每个活动中添加那一行,如果你在Application类中添加它一次也可以。
android {
defaultConfig {
vectorDrawables.useSupportLibrary = true
}
}
请记住:您仍然需要在gradle中启用支持库:
app:srcCompat
此外,当Google添加对VectorDrawables(release note)的Drawable Containers的支持时,请确保您使用的支持库版本大于v23.4
<强>更新强>
代码更改:
android:src
每个接受<bitmap>
属性的地方(如果drawableLeft
标记无效,IDE会向您发出警告)。对于drawableStart
和类似视图中使用的drawableRight
,drawableEnd
,TextView
,drawableStart
属性,您必须以编程方式设置它们现在。设置Drawable drawable = AppCompatResources.getDrawable(
getContext(),
R.drawable.your_vector_drawable);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1) {
textView.setCompoundDrawablesRelativeWithIntrinsicBounds(drawable, null, null, null);
}
:
{{1}}
答案 4 :(得分:12)
我遇到了同样的问题。并通过删除
来解决它vectorDrawables.useSupportLibrary = true
我的目标版本是25,支持库是
compile 'com.android.support:appcompat-v7:25.3.1'
答案 5 :(得分:8)
预棒棒糖上的VectorDrawables可以在不使用
的情况下正常工作AppCompatDelegate.setCompatVectorFromResourcesEnabled(true);
如果你想在ImageViews中使用VectorDrawables,你可以使用属性srcCompat
它可以工作,但在Buttons或TextViews中它不会,所以你需要包装可绘制为InsetDrawable或LayerDrawable。我发现了另一个技巧,如果你使用数据绑定,你可以这样做:
android:drawableLeft="@{@drawable/vector_ic_access_time_24px}"
android:drawableStart="@{@drawable/vector_ic_access_time_24px}"
这将神奇地起作用,我没有调查幕后发生的事情,但我猜TextView正在使用AppCompatResources中的getDrawable方法或类似方法。
答案 6 :(得分:5)
经过大量的研发,最终获得了解决此问题的解决方案,以解决棒棒糖前置设备上的崩溃问题。
对于Imageview
- 使用 app:srcCompat 代替android:src
对于TextView / EditText
- 删除 drawableleft , drawableright ....并从可绘制的Java代码中进行设置。
txtview.setCompoundDrawablesWithIntrinsicBounds(AppCompatResources.getDrawable(EventDetailSinglePage.this, R.drawable.ic_done_black_24_n),null,null,null);
对于Build.gradle
vectorDrawables.useSupportLibrary = true
答案 7 :(得分:4)
对于升级到android gradle 3.0及更高版本的任何人,无需使用AppCompatDelegate.setCompatVectorFromResourcesEnabled(true)
或设置vectorDrawables.useSupportLibrary = true
(添加此项会导致问题)并使用app:srcCompat
,它只是的工作原理。
我花了两天时间搞清楚这一点,并且在google的文档中找不到任何相关的文档......
答案 8 :(得分:2)
我在Pre-lollipop设备上使用VectorDrawables,这就是我的方法: -
第1步: 把它放在你的app level gradle中。
android {
defaultConfig {
vectorDrawables.useSupportLibrary = true
}
}
第2步:
将它放在Application类中,不要忘记在清单文件中注册Application类。
public class App extends Application {
static {
AppCompatDelegate.setCompatVectorFromResourcesEnabled(true);
}
}
第3步:
使用
获取VectorDrawablesimageView.setImageDrawable(ContextCompat.getDrawable(this, R.drawable.my_vector_drawable));
答案 9 :(得分:1)
我为此苦苦挣扎了好几个小时。
我尝试了所有这些答案告诉我的一切,但是我的应用没有停止崩溃。我删除了以下行:app:srcCompat="@drawable/keyboard"
,我的应用停止了崩溃。然后当我又添加了同样的东西时,它又开始崩溃了。因此,我决定打开该文件,并在第一行看到
“ drawable'Keyboard'在基本drawable中没有声明 夹;这可能会导致崩溃。
我右键单击该文件,然后单击“在资源管理器中显示”,它不是在drawable文件夹中,而是在drawable-v24目录中。所以我将其复制并粘贴到drawable目录中,最后摆脱了崩溃。
答案 10 :(得分:0)
只需将重叠向量绘制到状态列表即可解决问题
例如,您具有后退箭头矢量图像:
ic_back_arrow.xml
是的,您应该将其与图层列表xml(ic_back_arrow_vector_vector.xml)重叠:
<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
<item android:drawable="@drawable/ic_back_arrow"/>
</layer-list>
由于逻辑:
vectorDrawables.useSupportLibrary = true
和
AppCompatDelegate.setCompatVectorFromResourcesEnabled(true);
不能在某些中国设备和较旧的三星设备上为您提供帮助。如果您不重叠它们,它将失败。
答案 11 :(得分:0)
最简单的使用方式:
app:drawableRightCompat ="@drawable/ic_mobilelogin"
app:drawableEndCompat="@drawable/ic_mobilelogin"
app:srcCompat="@drawable/ic_mobile"
然后... 只需使用app:**为了兼容性而兼容
还添加了对buil.gradle(模块)的支持
android {
defaultConfig {
vectorDrawables.useSupportLibrary = true
}
}
答案 12 :(得分:0)
使用以下代码后。
android {
defaultConfig {
vectorDrawables.useSupportLibrary = true
}
}
public class App extends Application {
static {
AppCompatDelegate.setCompatVectorFromResourcesEnabled(true);
}}
仍然存在以下属性的矢量图像问题
DrawableEnd, DrawableStart, DrawableTop, DrawableBottom, 背景
在这种情况下,请按照以下说明进行操作,而不是直接参考矢量图像,请使用选择器标记作为中间可绘制文件。
示例:
ic_warranty_icon.xml
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="17dp"
android:height="24dp"
android:autoMirrored="true"
android:viewportWidth="17"
android:viewportHeight="24">
<path
android:fillColor="#fff"
android:pathData="M10.927,15.589l-1.549,0.355a7.47,7.47 0,0 1,-0.878 0.056c-4.136,0 -7.5,-3.364 -7.5,-7.5s3.364,-7.5 7.5,-7.5 7.5,3.364 7.5,7.5c0,3.286 -2.126,6.078 -5.073,7.089zM8.5,2a6.508,6.508 0,0 0,-6.5 6.5c0,3.583 2.917,6.5 6.5,6.5s6.5,-2.917 6.5,-6.5 -2.917,-6.5 -6.5,-6.5z" />
safe_ic_warranty_icon.xml
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:drawable="@drawable/ic_warranty_icon" />
</selector>
您的TextView /布局。
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:drawableStart="@drawable/ic_warranty_icon"
/>
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="@drawable/ic_warranty_icon"
/>
答案 13 :(得分:0)
我们尝试了三件事
vectorDrawables.useSupportLibrary = true
在应用程序类中设置setCompatVectorFromResourcesEnabled
static {
AppCompatDelegate.setCompatVectorFromResourcesEnabled(true);
}
并使用app:srcCompat
但是即使如此,它还是失败了
Resources$NotFoundException: File res/drawable/$my_icon__0.xml from color state list resource ID #0x7f080008
然后,我们发现SVG具有渐变标签。 对于低于API <= 23并使用相同的SVG API> = 24的情况,将渐变标签转换为单独的路径是可行的。
的帮助答案 14 :(得分:-2)
Guilherme P的建议不适合我。我继续做下决定使用png,我需要在app之外做一些事情:srcCompat,即drawableLeft,drawableRight等。这是一个非常简单的改变,并没有潜力内存问题AppCompatDelegate.setCompatVectorFromResourcesEnabled(true); 介绍。
答案 15 :(得分:-3)
Benny的答案的替代方法是创建Activity
超类:
public abstract class VectorDrawableActivity extends AppCompatActivity {
static {
AppCompatDelegate.setCompatVectorFromResourcesEnabled(true);
}
//...
}
现在扩展VectorDrawableActivity
而不是AppCompatActivity
。