文档章节

Android Vector 的兼容之路

中成才
 中成才
发布于 2016/07/06 15:09
字数 1525
阅读 355
收藏 1

####只兼容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以上:

android {
    defaultConfig {
        vectorDrawables.useSupportLibrary = true
    }
}

使用Gradle Plugin 2.0以下,Gradle Plugin 1.5以上:

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的支持:

compile 'com.android.support:appcompat-v7:23.4.0'

最低版本(如果之前是21, 后面还会引发新的坑): compileSdkVersion 23 buildToolsVersion '23.0.3'

同时,确保你使用的是AppCompatActivity而不是普通的Activity。

####Vector图像 一个基本的Vector图像,实际上也是一个xml文件,如下所示:

<vector xmlns:android="http://schemas.android.com/apk/res/android"
 android:width="200dp"
 android:height="200dp"
 android:viewportHeight="500"
 android:viewportWidth="500">

    <path
     android:name="square"
     android:fillColor="#000000"
     android:pathData="M100,100 L400,100 L400,400 L100,400 z" />
</vector>

显示如图所示:(略)

这里需要解释下这里的几个标签:

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即可,示例代码如下所示:

<ImageView
 android:id="@+id/iv"
 android:layout_width="wrap_content"
 android:layout_height="wrap_content"
 app:srcCompat="@drawable/vector_image" />

在代码中设置的话,代码如下所示:

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

<vector xmlns:android="http://schemas.android.com/apk/res/android"
 android:width="24dp"
 android:height="24dp"
 android:viewportHeight="24.0"
 android:viewportWidth="24.0">
    <path
     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" />
</vector>

selector2.xml

<vector xmlns:android="http://schemas.android.com/apk/res/android"
 android:width="24dp"
 android:height="24dp"
 android:viewportHeight="24.0"
 android:viewportWidth="24.0">
    <path
     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" />
</vector>

selector.xml

<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
    <item android:drawable="@drawable/selector1" android:state_pressed="true" />
    <item android:drawable="@drawable/selector2" />
</selector>

非常简单,只是把普通的Selector中的图像换成了Vector图像而已,接下来,在Button中使用这个Selector即可:

<Button
 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的前面就可以了:

static {
    AppCompatDelegate.setCompatVectorFromResourcesEnabled(true);
}

开启这个flag后,你就可以正常使用Selector这样的DrawableContainers了。同时,你还开启了类似android:drawableLeft这样的compound drawable的使用权限,以及RadioButton的使用权限,以及ImageView’s src属性。

#####RadioButton RadioButton的Button同样可以定义,代码如下所示:

<RadioButton
 android:layout_width="50dp"
 android:layout_height="50dp"
 android:button="@drawable/selector" />

本文转载自:http://www.itnose.net/detail/6528757.html

中成才
粉丝 55
博文 130
码字总数 51630
作品 0
海淀
架构师
私信 提问
Android SVG、Vector和VectorDrawable矢量图及动画

Vector图像,第三方Sharp库,阿里巴巴的SVG图。 阿里巴巴矢量图库(http://www.iconfont.cn/) Android矢量图(一)--VectorDrawable基础- https://www.jianshu.com/p/0972a0d290e9 android下一些...

desaco
2018/10/18
0
0
Android 网络编程 目录

Android 网络编程 目录 Android 网络编程1 Http协议 Android 网络编程2 Okhttp缓存机制 Android 网络编程3 Java NIO to be continued... Android 架构师之路 目录 Android 架构师之路1 UML图...

香沙小熊
2018/06/21
0
0
Android 制作逐渐显示动画(描边动画、矢量动画VectorDrawble)

传统的Android提供的动画只有平移、缩放、显示等效果,那么怎么才能实现逐渐绘制动画? 答案是使用矢量图动画。 一、 矢量图支持VectorDrawble Android 系统从5.0开始支持矢量图,可以通过 ...

Mr云台
2017/09/20
0
0
Android学习之路--新增兼容库分类

之前的这篇分享: 为Android开发者们写了篇博客,自己是过来人,希望能给学习Android开发的一些帮助,自己学习的时候走了不少弯路,希望你们少走弯路。 如今博客新整理添加了“Android兼容库...

stormzhang
2014/07/24
447
0
通用的C基础库 - Gear Lib

Gear Lib是一组通用的C基础库 全部用POSIX C实现,目标是为了跨平台兼容x86, arm, android, ios. 每个库都是一个独立工程,使用时,只需要把真正用到的库加入你的项目中即可,无需导入整个工...

gozfree
06/18
754
0

没有更多内容

加载失败,请刷新页面

加载更多

OpenStack 简介和几种安装方式总结

OpenStack :是一个由NASA和Rackspace合作研发并发起的,以Apache许可证授权的自由软件和开放源代码项目。项目目标是提供实施简单、可大规模扩展、丰富、标准统一的云计算管理平台。OpenSta...

小海bug
昨天
5
0
DDD(五)

1、引言 之前学习了解了DDD中实体这一概念,那么接下来需要了解的就是值对象、唯一标识。值对象,值就是数字1、2、3,字符串“1”,“2”,“3”,值时对象的特征,对象是一个事物的具体描述...

MrYuZixian
昨天
6
0
数据库中间件MyCat

什么是MyCat? 查看官网的介绍是这样说的 一个彻底开源的,面向企业应用开发的大数据库集群 支持事务、ACID、可以替代MySQL的加强版数据库 一个可以视为MySQL集群的企业级数据库,用来替代昂贵...

沉浮_
昨天
6
0
解决Mac下VSCode打开zsh乱码

1.乱码问题 iTerm2终端使用Zsh,并且配置Zsh主题,该主题主题需要安装字体来支持箭头效果,在iTerm2中设置这个字体,但是VSCode里这个箭头还是显示乱码。 iTerm2展示如下: VSCode展示如下: 2...

HelloDeveloper
昨天
7
0
常用物流快递单号查询接口种类及对接方法

目前快递查询接口有两种方式可以对接,一是和顺丰、圆通、中通、天天、韵达、德邦这些快递公司一一对接接口,二是和快递鸟这样第三方集成接口一次性对接多家常用快递。第一种耗费时间长,但是...

程序的小猿
昨天
9
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部