在前Lollipop崩溃时使用Android矢量Drawables

Beh*_*yar 81 android vector android-compatibility android-support-library android-drawable

我在Lollipop之前使用android中的矢量drawables,这些是我的一些库和工具版本:

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

我在我的应用级别添加了此属性 Build.Gradle

android {  
  defaultConfig {  
    vectorDrawables.useSupportLibrary = true  
   }  
}
Run Code Online (Sandbox Code Playgroud)

还值得一提的是,我使用了一个额外的drawable,如Android官方博客(此处链接)中所述的LayerDrawable(layer_list),用于设置外部矢量绘图的drawablesapp:srcCompat

<level-list xmlns:android="http://schemas.android.com/apk/res/android">
    <item android:drawable="@drawable/search"/>
</level-list>
Run Code Online (Sandbox Code Playgroud)

你会发现在app之外直接引用矢量drawable:srcCompat将在Lollipop之前失败.但是,AppCompat确实支持在另一个可绘制容器(如StateListDrawable,InsetDrawable,LayerDrawable,LevelListDrawable和RotateDrawable)中引用它们时加载矢量drawable.通过使用此 间接,您可以在TextView的android:drawableLeft属性中使用向量drawable,这通常不能支持向量drawable.

当我使用的app:srcCompat一切工作正常,但当我使用时:

android:background
android:drawableLeft
android:drawableRight
android:drawableTop
android:drawableBottom
Run Code Online (Sandbox Code Playgroud)

ImageView,ImageButton,TextViewEditText到棒棒糖之前,它引发厚望:

Caused by: android.content.res.Resources$NotFoundException: File res/drawable/search_toggle.xml from drawable resource ID #0x7f0200a9
Run Code Online (Sandbox Code Playgroud)

W0r*_*0le 82

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

根据这个POST:

对于AppCompat用户,由于版本23.2.0/23.2.1 (ISSUE 205236)中的实现中发现的问题,我们决定删除允许您使用Lollipop前设备上的资源使用矢量绘图的功能.使用app:srcCompat和setImageResource()继续工作.

如果您访问问题问题205236,它们似乎将来会启用,但内存问题不会很快修复:

在下一个版本中,我添加了一个opt-in API,您可以在其中重新启用已删除的VectorDrawable支持.它具有与以前相同的警告(内存使用和配置更新问题).

我有类似的问题.因此,在我的情况下,我将所有使用矢量绘制的图标从资源恢复到PNG图像(因为即使在他们提供再次启用它的选项之后,内存问题也会继续发生).

我不确定这是否是最好的选择,但它确定了我认为的所有崩溃.

UPDATE

他们在Android支持库23.4.0中重新启用了
VectorDrawable

对于AppCompat用户,我们添加了一个opt-in API,通过AppCompatDelegate.setCompatVectorFromResourcesEnabled(true)重新启用资源支持Vector Drawables(23.2中的行为) - 请记住,这仍然会导致内存使用问题和更新配置实例时出现问题,因此默认情况下禁用它.

也许,app:srcCompat设置现在已经过时,您只需要在适当的活动中启用它(但是,需要测试).

现在,要启用它,您必须执行以下操作:

android {
  defaultConfig {
    vectorDrawables.useSupportLibrary = true
  }
}

dependencies {
  compile 'com.android.support:appcompat-v7:23.2.0' // OR HIGHER
}
Run Code Online (Sandbox Code Playgroud)

  • 以下是选择加入说明https://plus.google.com/+AndroidDevelopers/posts/B7QhFkWZ6YX.不幸的是,VectorDrawables仍然没有使用Pre-Lollipop设备.我在支持库23.4.0上,并且在defaultConfig {}中调用了'generatedDensities = []'和'vectorDrawables.useSupportLibrary = true'. (4认同)

Sha*_*ime 61

我有同样的问题.但是做了很多研发我得到了答案.

对于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);
Run Code Online (Sandbox Code Playgroud)

并使用"AppCompatResources"获取drawable.


Dav*_*and 54

要详细说明其他非常好的答案,这里有一个可以帮助您的图表.如果您的支持库从23.4.0到至少25.1.0,则它是有效的.

VectorDrawable cheatsheet


Ben*_*nny 39

Guillherme P的答案非常棒.只是为了做一个小的改进,你不需要在每个活动中添加那一行,如果你在Application类中添加它一次也可以.

public class App extends Application {

static {
    AppCompatDelegate.setCompatVectorFromResourcesEnabled(true);
}
Run Code Online (Sandbox Code Playgroud)

记住:您仍然需要在gradle中启用支持库的使用:

android {
  defaultConfig {
    vectorDrawables.useSupportLibrary = true
  }
}
Run Code Online (Sandbox Code Playgroud)

另外,当Google添加对VectorDrawables的Drawable Containers的支持时,请确保您使用的支持库版本大于v23.4(发行说明)

更新

对于代码更改:

  1. 确保更新到app:srcCompat每个接受该android:src属性的地方(如果<bitmap>标签无效,IDE会发出警告).
  2. 对于drawableLeft,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);
    }
    
    Run Code Online (Sandbox Code Playgroud)

  • 这种方法仍然不适用于drawables. (4认同)
  • 是的.我知道.但是有必要使用一个包装器来使矢量drawables作为TexViews的drawables,所以这个答案是不完整的. (2认同)

Raj*_*sit 13

我有同样的问题.并通过删除来修复它

vectorDrawables.useSupportLibrary = true
Run Code Online (Sandbox Code Playgroud)

我的目标版本是25,支持库是

 compile 'com.android.support:appcompat-v7:25.3.1'
Run Code Online (Sandbox Code Playgroud)


ces*_*rds 9

预棒棒糖上的VectorDrawables应该可以正常工作而不使用

AppCompatDelegate.setCompatVectorFromResourcesEnabled(true);
Run Code Online (Sandbox Code Playgroud)

如果你想在ImageViews中使用VectorDrawables,你可以使用该属性srcCompat,它可以工作,但在Buttons或TextViews中它不会,所以你需要将Drawable包装成InsetDrawable或LayerDrawable.我发现了另一个技巧,如果你使用数据绑定,你可以这样做:

android:drawableLeft="@{@drawable/vector_ic_access_time_24px}"
android:drawableStart="@{@drawable/vector_ic_access_time_24px}"
Run Code Online (Sandbox Code Playgroud)

这将神奇地工作,我没有调查幕后发生的事情,但我想TextView正在使用AppCompatResources或类似的getDrawable方法.


Ham*_*ani 7

最简单的使用方法:

app:drawableRightCompat ="@drawable/ic_mobilelogin"
app:drawableEndCompat="@drawable/ic_mobilelogin"
app:srcCompat="@drawable/ic_mobile"
Run Code Online (Sandbox Code Playgroud)

和...只是 app:**Compat用于兼容性。还添加对build.gradle(模块)的支持

android {
   defaultConfig {
       vectorDrawables.useSupportLibrary = true
   }
}
Run Code Online (Sandbox Code Playgroud)


Jat*_*nka 6

很多研发,终于在棒棒糖前设备上获得了崩溃的解决方案.

对于Imageview

  • 使用app:srcCompat而不是android:src

对于TextView/EditText

  • 删除drawableleft,drawableright ....并从drawable java代码设置.

txtview.setCompoundDrawablesWithIntrinsicBounds(AppCompatResources.getDrawable(EventDetailSinglePage.this,R.drawable.ic_done_black_24_n),null,null,null);

对于Build.gradle

vectorDrawables.useSupportLibrary = true


Gen*_*wen 5

对于升级到android gradle 3.0及更高版本的任何人,都无需使用AppCompatDelegate.setCompatVectorFromResourcesEnabled(true)或进行设置vectorDrawables.useSupportLibrary = true(添加它会导致问题)和use app:srcCompat,它就可以正常工作。

请花两天时间来解决这个问题,并且在Google文档中找不到任何相关文档...


归档时间:

查看次数:

49632 次

最近记录:

5 年,11 月 前