rawable/abc_vector_test.xml from drawable resource ID #0x7f020052

在build.gradle文件中添加以下代码:
aaptOptions {
additionalParameters "--no-version-vectors"
}

只兼容L+
Vector是在Android L中提出来的新概念,所以在刚开始的时候是只兼容L+的。
####Gradle Plugin 1.5的兼容
从Gradle Plugin 1.5开始,Google支持了一种兼容方式,即在Android L之上,使用Vector,而在L之下,则使用Gradle将Vector生成PNG图像。
Android gradle plugin 1.5发布以后,加入了一个跟VectorDrawable有关的新功能。Android build tools 提供了另外一种解决兼容性的方案,如果编译的版本是5.0之前的版本,那么build tools 会把VectorDrawable生成对应的png图片,这样在5.0以下的版本则使用的是生成的png图,而在5.0以上的版本中则使用VectorDrawable.在build.gradle添加generatedDensities配置,可以配置生成的png图片的密度。
####AppCompat23.2的兼容
从AppCompat23.2开始,Google开始支持在低版本上使用Vector。
*静态Vector图像
我们有很多方法能够得到这些Vector,那么如何使用它们呢,Android 5.0以上的使用就不讲了,不太具有普遍代表性,我们从pre-L版本的兼容开始做起。
####pre-L版本兼容
VectorDrawableCompat依赖于AAPT的一些功能,它能保持最近矢量图使用的添加的属性ID,以便他们可以被pre-L版本之前的引用。
在Android 5.0之前使用Vector,需要aapt来对资源进行一些处理,这一过程可以在aapt的配置中进行设置,如果没有启用这样一个flag,那么在5.0以下的设备上运行就会发生android.content.res.Resources$NotFoundException。
首先,你需要在项目的build.gradle脚本中,增加对Vector兼容性的支持,代码如下所示:
使用Gradle Plugin 2.0以上:
Gradle
android {
defaultConfig {
vectorDrawables.useSupportLibrary = true
}
}

使用Gradle Plugin 2.0以下,Gradle Plugin 1.5以上:
Gradle
android {
defaultConfig {
// Stops the Gradle plugin’s automatic rasterization of vectors
generatedDensities = []
}
// Flag to tell aapt to keep the attribute ids around
aaptOptions {
additionalParameters "--no-version-vectors"
}
}

像前面提到的,这种兼容方式实际上是先关闭AAPT对pre-L版本使用Vector的妥协,即在L版本以上,使用Vector,而在pre-L版本上,使用Gradle生成相应的PNG图片,generatedDensities这个数组,实际上就是要生成PNG的图片分辨率的数组,使用appcompat后就不需要这样了。
当然,最重要的还是添加appcompat的支持:
Gradle
compile 'com.android.support:appcompat-v7:23.4.0'

>最低版本(如果之前是21, 后面还会引发新的坑):
compileSdkVersion 23
buildToolsVersion '23.0.3'
同时,确保你使用的是AppCompatActivity而不是普通的Activity。
####Vector图像
一个基本的Vector图像,实际上也是一个xml文件,如下所示:
Xml
android:width="200dp"
android:height="200dp"
android:viewportHeight="500"
android:viewportWidth="500">
android:name="square"
android:fillColor="#000000"
android:pathData="M100,100 L400,100 L400,400 L100,400 z" />


显示如图所示:(略)
这里需要解释下这里的几个标签:
>android:width / android:height:定义图片的宽高
android:viewportHeight / android:viewportWidth:定义图像被划分的比例大小,例如例子中的500,即把200dp大小的图像划分成500份,后面Path标签中的坐标,就全部使用的是这里划分后的坐标系统。
这样做有一个非常好的作用,就是将图像大小与图像分离,后面可以随意修改图像大小,而不需要修改PathData中的坐标。
android:fillColor:PathData中的这些属性就不详细讲了,与Canvas绘图的属性基本类似。
####在控件中使用
有了静态的Vector图像,就可以在控件中使用了。
可以发现,这里我们使用的都是普通的ImageView,好像并不是AppcomatImageView,这是因为使用了Appcomat后,系统会自动把ImageView转换为AppcomatImageView。
#####ImageView/ImageButton
对于ImageView这样的控件,要兼容Vector图像,只需要将之前的android:src属性,换成app:srcCompat即可,示例代码如下所示:
Xml
android:id="@+id/iv"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:srcCompat="@drawable/vector_image" />

在代码中设置的话,代码如下所示:
Java
ImageView iv = (ImageView) findViewById(R.id.iv);
iv.setImageResource(R.drawable.vector_image);
// setBackgroundResource也是可以设置Vector的API

#####Button
Button并不能直接使用app:srcCompat来使用Vector图像,需要通过Selector来进行使用,首先,创建两个图像,用于Selector的两个状态,代码如下所示:
selector1.xml
Xml
android:width="24dp"
android:height="24dp"
android:viewportHeight="24.0"
android:viewportWidth="24.0">
android:fillColor="#FF000000"
android:pathData="M14.59,8L12,10.59 9.41,8 8,9.41 10.59,12 8,14.59 9.41,16 12,13.41 14.59,16 16,14.59 13.41,12 16,9.41 14.59,8zM12,2C6.47,2 2,6.47 2,12s4.47,10 10,10 10,-4.47 10,-10S17.53,2 12,2zM12,20c-4.41,0 -8,-3.59 -8,-8s3.59,-8 8,-8 8,3.59 8,8 -3.59,8 -8,8z" />


selector2.xml
Xml
android:width="24dp"
android:height="24dp"
android:viewportHeight="24.0"
android:viewportWidth="24.0">
android:fillColor="#FF000000"
android:pathData="M11,15h2v2h-2zM11,7h2v6h-2zM11.99,2C6.47,2 2,6.48 2,12s4.47,10 9.99,10C17.52,22 22,17.52 22,12S17.52,2 11.99,2zM12,20c-4.42,0 -8,-3.58 -8,-8s3.58,-8 8,-8 8,3.58 8,8 -3.58,8 -8,8z" />


selector.xml
Xml






非常简单,只是把普通的Selector中的图像换成了Vector图像而已,接下来,在Button中使用这个Selector即可:
Xml
android:id="@+id/btn"
android:layout_width="70dp"
android:layout_height="70dp"
android:background="@drawable/selector" />

然后运行,如果你认为可以运行,那就是太天真了,都说了是兼容,怎么能没有坑呢,这里就是一个坑……
这个坑实际上是有历史渊源的,Google的一位开发者在博客中写到:
>First up, this functionality was originally released in 23.2.0, but then we found some memory usage and Configuration updating issues so we it removed in 23.3.0. In 23.4.0 (technically a fix release) we’ve re-added the same functionality but behind a flag which you need to manually enable.
实际上,他们的这个改动,就影响了类似DrawableContainers(DrawableContainers which reference other drawables resources which contain only a vector resource)这样的类,它的一个典型,就是Selector(StateListDrawable也是)。这个开发者在文中提到的flag,就是下面的这段代码,放在Activity的前面就可以了:
Java
static {
AppCompatDelegate.setCompatVectorFromResourcesEnabled(true);
}

开启这个flag后,你就可以正常使用Selector这样的DrawableContainers了。同时,你还开启了类似android:drawableLeft这样的compound drawable的使用权限,以及RadioButton的使用权限,以及ImageView’s src属性。
#####RadioButton
RadioButton的Button同样可以定义,代码如下所示:
Xml
android:layout_width="50dp"
android:layout_height="50dp"
android:button="@drawable/selector" />

你可能感兴趣的:(rawable/abc_vector_test.xml from drawable resource ID #0x7f020052)