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<br>android {<br>defaultConfig {<br> vectorDrawables.useSupportLibrary = true<br>}<br>}<br>
使用Gradle Plugin 2.0以下,Gradle Plugin 1.5以上:
Gradle<br>android {<br>defaultConfig {<br>// Stops the Gradle plugin’s automatic rasterization of vectors<br>generatedDensities = []<br>}<br>// Flag to tell aapt to keep the attribute ids around<br>aaptOptions {<br>additionalParameters "--no-version-vectors"<br>}<br>}<br>
像前面提到的,这种兼容方式实际上是先关闭AAPT对pre-L版本使用Vector的妥协,即在L版本以上,使用Vector,而在pre-L版本上,使用Gradle生成相应的PNG图片,generatedDensities这个数组,实际上就是要生成PNG的图片分辨率的数组,使用appcompat后就不需要这样了。
当然,最重要的还是添加appcompat的支持:
Gradle<br>compile 'com.android.support:appcompat-v7:23.4.0'<br>
>最低版本(如果之前是21, 后面还会引发新的坑):
compileSdkVersion 23
buildToolsVersion '23.0.3'
同时,确保你使用的是AppCompatActivity而不是普通的Activity。
####Vector图像
一个基本的Vector图像,实际上也是一个xml文件,如下所示:
Xml<br><vector xmlns:android="http://schemas.android.com/apk/res/android"<br> android:width="200dp"<br> android:height="200dp"<br> android:viewportHeight="500"<br> android:viewportWidth="500"><br><path<br> android:name="square"<br> android:fillColor="#000000"<br> android:pathData="M100,100 L400,100 L400,400 L100,400 z" /><br></vector><br>
显示如图所示:(略)
这里需要解释下这里的几个标签:
>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<br><ImageView<br> android:id="@+id/iv"<br> android:layout_width="wrap_content"<br> android:layout_height="wrap_content"<br> app:srcCompat="@drawable/vector_image" /><br>
在代码中设置的话,代码如下所示:
Java<br>ImageView iv = (ImageView) findViewById(R.id.iv);<br>iv.setImageResource(R.drawable.vector_image);<br>// setBackgroundResource也是可以设置Vector的API<br>
#####Button
Button并不能直接使用app:srcCompat来使用Vector图像,需要通过Selector来进行使用,首先,创建两个图像,用于Selector的两个状态,代码如下所示:
selector1.xml
Xml<br><vector xmlns:android="http://schemas.android.com/apk/res/android"<br> android:width="24dp"<br> android:height="24dp"<br> android:viewportHeight="24.0"<br> android:viewportWidth="24.0"><br><path<br> android:fillColor="#FF000000"<br> 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" /><br></vector><br>
selector2.xml
Xml<br><vector xmlns:android="http://schemas.android.com/apk/res/android"<br> android:width="24dp"<br> android:height="24dp"<br> android:viewportHeight="24.0"<br> android:viewportWidth="24.0"><br><path<br> android:fillColor="#FF000000"<br> 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" /><br></vector><br>
selector.xml
Xml<br><?xml version="1.0" encoding="utf-8"?><br><selector xmlns:android="http://schemas.android.com/apk/res/android"><br><item android:drawable="@drawable/selector1" android:state_pressed="true" /><br><item android:drawable="@drawable/selector2" /><br></selector><br>
非常简单,只是把普通的Selector中的图像换成了Vector图像而已,接下来,在Button中使用这个Selector即可:
Xml<br><Button<br> android:id="@+id/btn"<br> android:layout_width="70dp"<br> android:layout_height="70dp"<br> android:background="@drawable/selector" /><br>
然后运行,如果你认为可以运行,那就是太天真了,都说了是兼容,怎么能没有坑呢,这里就是一个坑……
这个坑实际上是有历史渊源的,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<br>static {<br>AppCompatDelegate.setCompatVectorFromResourcesEnabled(true);<br>}<br>
开启这个flag后,你就可以正常使用Selector这样的DrawableContainers了。同时,你还开启了类似android:drawableLeft这样的compound drawable的使用权限,以及RadioButton的使用权限,以及ImageView’s src属性。
#####RadioButton
RadioButton的Button同样可以定义,代码如下所示:
Xml<br><RadioButton<br> android:layout_width="50dp"<br> android:layout_height="50dp"<br> android:button="@drawable/selector" /><br>

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 194,457评论 5 459
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 81,837评论 2 371
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 141,696评论 0 319
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 52,183评论 1 263
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 61,057评论 4 355
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 46,105评论 1 272
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 36,520评论 3 381
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 35,211评论 0 253
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 39,482评论 1 290
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 34,574评论 2 309
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 36,353评论 1 326
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 32,213评论 3 312
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 37,576评论 3 298
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 28,897评论 0 17
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,174评论 1 250
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 41,489评论 2 341
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 40,683评论 2 335

推荐阅读更多精彩内容