栅格图可以实现图片的清晰显示,但这也意味着如果要在各种设备上使用栅格图,那么在使用的时候就会产生为了适配各种尺寸的设备而增加大量不同规格的栅格图,这也直接导致了资源文件体积的增大,矢量图就不存在这个问题,这里就介绍一种矢量图–SVG

SVG的简介

SVG可缩放矢量图形(Scalable Vector Graphics)是基于可扩展标记语言(XML),用于描述二维矢量图形的一种图形格式。SVG是W3C(World Wide Web ConSortium国际互联网标准组织)在2000年8月制定的一种新的二维矢量图形格式,也是规范中的网络矢量图形标准。SVG严格遵从XML语法,并用文本格式的描述性语言来描述图像内容,因此是一种和图像分辨率无关的矢量图形格式

SVG优势

  • 可被非常多的工具读取和修改(比如记事本)
  • 与 JPEG 和 GIF 图像比起来,尺寸更小,且可压缩性更强。
  • 是可伸缩的
  • 图像可在任何的分辨率下被高质量地打印
  • 可在图像质量不下降的情况下被放大
  • 图像中的文本是可选的,同时也是可搜索的(很适合制作地图)
  • 可以与 Java 技术一起运行
  • 是开放的标准
  • 文件是纯粹的 XML

以上内容引用自百度百科和W3C

Android中的矢量图为Vector Drawable,可以说Vector就是Android中的SVG实现(并不是支持全部的SVG语法,现已支持的完全足够用了),其最低支持2.1(23.2+),不过这种支持是将SVG转化为PNG,在5.0及以上就直接使用SVG

Vector Drawable

Android 5.0发布的时候,Google提供了Vector的支持,即:Vector Drawable类

Vector Drawable相对于普通的Drawable来说,有以下几个好处

  1. Vector图像可以自动进行适配,不需要通过分辨率来设置不同的图片
  2. Vector图像可以大幅减少图像的体积,同样一张图,用Vector来实现,可能只有PNG的几十分之一
  3. 使用简单,很多设计工具,都可以直接导出SVG图像,从而转换成Vector图像 功能强大
  4. 不用写很多代码就可以实现非常复杂的动画 成熟、稳定,前端已经非常广泛的进行使用了

Vector 语法简介

通过使用它的Path标签,几乎可以实现SVG中的其它所有标签,虽然可能会复杂一点,但这些东西都是可以通过工具来完成的,所以,不用担心写起来会很复杂

Path指令解析如下所示:

M = moveto(M X,Y):将画笔移动到指定的坐标位置,相当于android Path里的moveTo()

L = lineto(L X,Y):画直线到指定的坐标位置,相当于android Path里的lineTo()

H = horizontal lineto(H X):画水平线到指定的X坐标位置

V = vertical lineto(V Y):画垂直线到指定的Y坐标位置

C = curveto(C X1,Y1,X2,Y2,ENDX,ENDY):三次贝赛曲线

S = smooth curveto(S X2,Y2,ENDX,ENDY):同样三次贝塞尔曲线,更平滑

Q = quadratic Belzier curve(Q X,Y,ENDX,ENDY):二次贝赛曲线

T = smooth quadratic Belzier curveto(T ENDX,ENDY):映射 同样二次贝塞尔曲线,更平滑

A = elliptical Arc(A RX,RY,XROTATION,FLAG1,FLAG2,X,Y):弧线,相当于arcTo()

Z = closepath():关闭路径(会自动绘制连接起点和终点)

注意: M处理时,只是移动了画笔,没有画任何东西

  1. 关于这些语法,开发者不需要全部精通,而是能够看懂即可,这些path标签及数据生成都可以交给工具来实现(一般美工来帮你搞定!PS、Illustrator等等都支持导出SVG图片)
  2. 程序员:没必要去学习使用这些设计工具,开发者可以利用一些工具,自己转换一些比较基础的图像,如:http://inloop.github.io/svg2android/
  3. 还可以使用SVG的编辑器来进行SVG图像的编写,例如:http://editor.method.ac/ (绝配!可以先用 http://editor.method.ac/ 生成SVG图片,然后用 http://inloop.github.io/svg2android/ 生成 VectorDrawable xml代码)
  4. 使用AndroidStudio插件完成SVG添加(Vector Asset Studio)AS会自动生成兼容性图片(高版本会生成xxx.xml的SVG图片;低版本会自动生成xxx.png图片)
  5. 有些网站可以找到SVG资源,SVG下载地址: http://www.shejidaren.com/8000-flat-icons.htmlhttp://www.flaticon.com/

静态Vector图像

生成图片

例如:我们用as生成的一个图片如下

<vector android:alpha="0.78" android:height="24dp"
android:viewportHeight="24.0" android:viewportWidth="24.0"
android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android">
<path android:fillColor="#FF000000" android:pathData="M19.35,10.04C18.67,6.59 15.64,4 12,4 9.11,4 6.6,5.64 5.35,8.04 2.34,8.36 0,10.91 0,14c0,3.31 2.69,6 6,6h13c2.76,0 5,-2.24 5,-5 0,-2.64 -2.05,-4.78 -4.65,-4.96zM14,13v4h-4v-4H7l5,-5 5,5h-3z"/>
</vector>

和 (一个矩形)

<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中的坐标

使用图片,就当普通的图片使用就可以了。

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

或者代码设置

ImageView iv = (ImageView) findViewById(R.id.iv);
iv.setImageResource(R.drawable.vector_image);
iv.setBackgroundResource(R.drawable.vector_image)

如果是Button,可以设置selector(写两个SVG的Drawable)

<?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>

动态Vector

动态Vector才是Android Vector Drawable的精髓所在

具体可参见 http://www.jianshu.com/p/e3614e7abc03

git项目位置:https://github.com/xuyisheng/VectorDemo

animated-vector: 只能5.+才能使用

如果是两个SVG进行动画,要注意两个SVG的节点一定要一样多(命令数要一样)

下面举一个例子

初始状况path_tick.xml,这里定义了一张vector图片

<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="120dp"
android:height="120dp"
android:viewportHeight="24"
android:viewportWidth="24">
<group>
<path
android:name="tickCrossGroup"
android:pathData="M19.6,7 L10.4,16.2 M4.8,13.4 L9,17.6"
android:strokeColor="#000"
android:strokeWidth="2" />
</group>
</vector>

动画集合anim_path_tick2cross.xml,指定具体动画过程

<set xmlns:android="http://schemas.android.com/apk/res/android">
<objectAnimator
android:duration="300"
android:propertyName="pathData"
android:valueFrom="M19.6,7 L10.4,16.2 M4.8,13.4 L9,17.6"
android:valueTo="M17.6,6.4 L6.4,17.6 M6.4,6.4 L17.6,17.6"
android:valueType="pathType" />
</set>

移动方式path_tick2cross_anim.xml

<animated-vector xmlns:android="http://schemas.android.com/apk/res/android"
android:drawable="@drawable/path_tick">
<target
android:name="tickCrossGroup"
android:animation="@anim/anim_path_tick2cross" />
</animated-vector>

然后使用一个ImageView设置src

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"> <ImageView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:onClick="startAnim"
android:src="@drawable/path_tick2cross_anim" />
</LinearLayout>

设置点击事件

public void startAnim(View view) {
ImageView iv = (ImageView) view;
Drawable drawable = iv.getDrawable();
if(drawable instanceof Animatable){
((Animatable)drawable).start();
}
}

效果如下图

VectorDrawable的性能问题:

  • Bitmap的绘制效率并不一定会比Vector高,它们有一定的平衡点,当Vector比较简单时,其效率是一定比Bitmap高的,所以,为了保证Vector的高效率,Vector需要更加简单,PathData更加标准、精简,当Vector图像变得非常复杂时,就需要使用Bitmap来代替了
  • Vector适用于ICONButtonImageView的图标等小的ICON,或者是需要的动画效果,由于BitmapGPU中有缓存功能,而Vector并没有,所以Vector图像不能做频繁的重绘
  • Vector图像过于复杂时,不仅仅要注意绘制效率,初始化效率也是需要考虑的重要因素

使用实例

首先在 https://editor.method.ac/ 生成一张svg格式的图片,然后下载下来,可以看到下载下来的是一个svg格式的文件



然后将下载的svg格式文件拖入到 http://inloop.github.io/svg2android/ 中,此时便生成了android可用的图片格式



在这个网站使用的时候,能看到Android Studio已经集成了这个功能,也就是说Android Studio可以直接使用工具转化SVG,这个后面讲

经过上述步骤,便已经生成Android可用的svg了,此时将其内容拷贝到项目中

此时在预览时侯就能看到生成的图像了



导入的svg和平时的png使用方法一样,就当成一张png来使用就可以了

再来看看Android Studio是怎么转换SVG的,New -> Vector Asset -> local file

然后就可以生成Android可用的资源了,刚才我导出的那张SVG,在网站上转换没问题,但这这里却转换不成功,说明在这个功能上,Studio还有一定欠缺,当已经够用了



详细说明参照Android官网

其实ic_launcher_background.xml这个文件也是使用的这种方式

使用时候发现,仍有地方会报错,这其实是引用链接出的错,经过思考,这里直接在网站上复制而不要下载就可以解决这个情况

error: 'url(#gridpattern)' is incompatible with attribute android:fillColor (attr) color.

将其适当修改便可以了

android:fillColor="url(#gridpattern)"改为合适的填充颜色

顺利使用

高级UI-SVG的更多相关文章

  1. firefox 扩展开发笔记(三):高级ui交互编程

    firefox 扩展开发笔记(三):高级ui交互编程 前言 前两篇链接 1:firefox 扩展开发笔记(一):jpm 使用实践以及调试 2:firefox 扩展开发笔记(二):进阶开发之移动设备模拟 ...

  2. Android 高级UI设计笔记07:RecyclerView 的详解

    1. 使用RecyclerView       在 Android 应用程序中列表是一个非常重要的控件,适用场合非常多,如新闻列表.应用列表.消息列表等等,但是从Android 一出生到现在并没有非常 ...

  3. 高级UI特效—用SVG码造一个精美的中国地图

    前言 来继续学习SVG,要想深入了解还是要多动手进行实战.关于svg基础可以去看一下我的上一篇文章<SVG前戏—让你的View多姿多彩>,今天就用SVG打造一个精美的UI效果. 正文 先上 ...

  4. iOS开发——高级UI&带你玩转UITableView

    带你玩装UITableView 在实际iOS开发中UITableView是使用最多,也是最重要的一个控件,如果你不会用它,那别说什么大神了,菜鸟都不如. 其实关于UItableView事非常简单的,实 ...

  5. 高级UI晋升之自定义View实战(六)

    更多Android高级架构进阶视频学习请点击:https://space.bilibili.com/474380680本篇文章将从Android 自定义属性动画&Camera动画来介绍自定义V ...

  6. 高级UI晋升之布局ViewGroup(四)

    更多Android高级架构进阶视频学习请点击:https://space.bilibili.com/474380680本篇文章将从LinearLayout.RelativeLayout.FrameLa ...

  7. 高级UI晋升之常用View(三)中篇

    更多Android高级架构进阶视频学习请点击:https://space.bilibili.com/474380680本篇文章将从ViewPager来介绍常用View:文章目录 一.简介 二.基本使用 ...

  8. 高级UI晋升之View渲染机制(二)

    更多Android高级架构进阶视频学习请点击:https://space.bilibili.com/474380680 优化性能一般从渲染,运算与内存,电量三个方面进行,今天开始说聊一聊Android ...

  9. 高级UI晋升之触摸事件分发机制(一)

    更多Android高级架构进阶视频学习请点击:https://space.bilibili.com/474380680 0. 前言 鉴于安卓分发机制较为复杂,故分为多个层次进行讲解,分别为基础篇.实践 ...

  10. Android 高级UI设计笔记21:Android SegmentView(分段选择控件)

    1. 分段控制(SegmentView) 首先我们先看看什么是SegmentView的效果,如下: 分段控制这个View控件是ios7的分段控制,和QQ消息页面顶部的效果一样,android没有这个控 ...

随机推荐

  1. cube.js 学习(四)cube.js cube 说明

      cube 是cube.js data schema 的核心,里面定义了生成sql 的说明 一个比较全的schema 例子 cube(`Users`, { sql: `select * from u ...

  2. zabbix的历史数据存储到elasticsearch中

    基本配置项 https://www.jianshu.com/p/bffca8128e8f 官方说这个实验性的功能支持es的版本是5.0.x - > 6.1.x,如果使用早期或更高版本的Elast ...

  3. linux共享文件 - samba 服务器

    1.Samba  服务器 客户端 yum 安装: # yum install samba samba-client -y 2.samba 配置文件配置 /etc/samba/smb.conf [glo ...

  4. (14)Go导入包几种方式

    (1)一般方式[导入单个和多个] (2)匿名导入包/忽略包  (主要用到有些包的init函数) (3)点操作包 (4)包别名/自定义包名 package main ////导入单个包 //import ...

  5. MySQL:服务无法启动(1067)问题

    打开安装文件下的my.ini 找到: #Path to the database rootdatadir="C:/ProgramData/MySQL/MySQL Server 5.5/dat ...

  6. Redis哨兵日志说明

    一.说明

  7. nginx+keepalived高可用实战

    1.整体架构图如下 2.环境准备 今天所配置的是keepalived+nginx 的负载均衡 下载keepalived软件 [root@LB01 tools]# wget http://www.kee ...

  8. sql查询性能调试,用SET STATISTICS IO和SET STATISTICS TIME---解释比较详细

            一个查询需要的CPU.IO资源越多,查询运行的速度就越慢,因此,描述查询性能调节任务的另一种方式是,应该以一种使用更少的CPU.IO资源的方式重写查询命令,如果能够以这样一种方式完成查 ...

  9. SQL学习笔记(二)

    连接查询 数据准备 例1:查询学生信息及学生的成绩 等值连接 此方法会产生笛卡尔积,生成的记录总数=表1的总数*表2的总数,会产生临时表 内连接 select * from 表1 inner join ...

  10. SQL学习笔记(一)

    逻辑删除 所谓的逻辑删除其实并不是真正的删除,而是在表中将对应的是否删除标识或者字段做修改操作.在逻辑上数据是被删除的,但数据本身依然存在库中 例如 update students3 set isde ...