什么是SVG

SVG的全称是Scalable Vector Graphics,叫可缩放矢量图形。是一种基于可扩展标记语言(XML)。它和位图(Bitmap)相对,SVG不会像位图一样因为缩放而让图片质量下降。它的优点在于节约空间,使用方便。

svg的优点

首先简要解释一下矢量图像格式和位图图像格式的区别。矢量图像用点和线来描述物体,所以文件会比较小,同时也能提供高清晰的画面,适合于直接打印或输出。而位图图像的存储单位是图像上每一点的像素值,因此一般的图像文件都很大,会占用大量的网络带宽。SVG是一种矢量图形格式,GIF、JPEG是光栅文件格式。有了两者的概念后,SVG较GIF、JPEG的优势显而易见。

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

推荐项目学习地址

https://github.com/geftimov/android-pathview

使用方法:

svg是在Android于5.0版本将该特性引入(Lollipop, API 21)。今天我们就讨论 一下在5.0以上版本中使用方法。

1)生成svg

1、可以找美工用PS或者是AI设计成图片后利用第三方工具进行转化为svg,以便我们能方便拿到svg数据

2、利用 Android Studio 具动态生成位图,Studio内置一个名为 Vector Asset Studio 的工具,在低版本SDK上编译APK期间,针对VectorDrawable脚本自动生成一组PNG位图资源BitmapDrawable,取代矢量图形(在5.0及以后的手机上运行时会正常引用VectorDrawable)。

 
 

需要配置build.gradle:

  1. defaultConfig {
  2. vectorDrawables.generatedDensities = ['hdpi','xxhdpi']
  3. }
2)将普通SVG图片数据转换成Android可用数据

一般的SVG图片数据是直接在html或jsp中可以使用,对我们android开发者来讲是要 拿到svg.xml的资源的,我们可以使用NotPad++打开,查看源码

 
 
解析SVG数据

我们知道,svg是以xml数据格式来进行描述的,既然svg本质上就是xml文件,所以从解析角度来看,能解析xml文件的工具应该几乎都可以用来解析svg文件。

1、DOM解析
查看Android源码可以看出,5.0引入svg后并没有使用dom进行解析svg源文件,虽然svg号称完全支持dom标准。笔者从dom解析的过程可以看出,Dom解析是将xml文件全部载入,组装成一颗dom树,然后通过节点以及节点之间的关系来解析xml文件。虽然一般情况下,svg文件是比较小的,但也不乏有些很复杂的图片会上升到M级别,如果在解析时需要全部载入,对于Android系统来说时比较耗时的,这也许就是dom遭Android淘汰的原因之一吧。
2、SAX解析
SAX(Simple API for XML)解析器是一种基于事件的解析器,它的核心是事件处理模式,主要是围绕着事件源以及事件处理器来工作的。当事件源产生事件后,调用事件处理器相应的处理方法,一个事件就可以得到处理。在事件源调用事件处理器中特定方法的时候,还要传递给事件处理器相应事件的状态信息,这样事件处理器才能够根据提供的事件信息来决定自己的行为。SAX解析器的优点是解析速度快,占用内存少。非常适合在Android移动设备中使用
3、PUll解析
PULL解析器的运行方式和SAX类似,都是基于事件的模式。不同的是,在PULL解析过程中,我们需要自己获取产生的事件然后做相应的操作,而不像 SAX那样由处理器触发一种事件的方法,执行我们的代码。PULL解析器小巧轻便,解析速度快,简单易用,非常适合在Android移动设备中使 用,Android系统内部在解析各种XML时也是用PULL解析器

一般这种方式我们只有自定义View进行解析

创建View,开启线程,进行解析,可以自己自己的需求进行绘制和加载相应的动画

布局中正常加载View一样加载解析出来的svg

备注如果对于简单的已有svg的 vectordrawable.xml,直接可以如对ImageView设置背景动画

  1. <?xml version="1.0" encoding="utf-8"?>
  2. <vector xmlns:android="http://schemas.android.com/apk/res/android"
  3. android:height="64dp"
  4. android:width="64dp"
  5. android:viewportHeight="600"
  6. android:viewportWidth="600" >
  7. <group
  8. android:name="rotationGroup"
  9. android:pivotX="300.0"
  10. android:pivotY="300.0"
  11. android:rotation="45.0" >
  12. <path
  13. android:name="v"
  14. android:fillColor="#000000"
  15. android:pathData="M300,70 l 0,-70 70,70 0,0 -70,70z" />
  16. </group>
  17. </vector>
  18. <?xml version="1.0" encoding="utf-8"?>
  19. <animated-vector xmlns:android="http://schemas.android.com/apk/res/android"
  20. android:drawable="@drawable/vectordrawable">
  21. <target
  22. android:name="rotationGroup"
  23. android:animation="@animator/rotation" />
  24. <target
  25. android:name="v"
  26. android:animation="@animator/path_morph" />
  27. </animated-vector>
  1. Drawable drawable = iv.getDrawable();
  2. if (drawable instanceof Animatable) {
  3. Animatable able = (Animatable) drawable;
  4. able.start();
  5. }

这种方式可以帮助我们解决用原生实现起来比较麻烦的一些特殊的需求。

 
 
 
多边形
 
六边形控件

使用SVG需要注意的是

一、SVG是在Android 5.0之后才支持的,所以如果想支持5.0之前的版本,最好使用兼容库。具体使用如下:

在build.gradle的defaultConfig中添加

  1. vectorDrawables.useSupportLibrary = true

二、继承AppCompatActivity

Activity也需要继承AppCompatActivity

另外:如果想在Activity代码中动态设置SVG(VectorDrawable), 需要动态添加兼容

  1. AppCompatDelegate.setCompatVectorFromResourcesEnabled(true);

三、显示问题

1、 UI给的SVG图片应该显示的是白色,但是在Android设备上显示的确实黑色
2、 在某些手机上SVG会出现锯齿,给用户造成的感觉就是字体style都不一样

一般情况下UI给我们的SVG图片可能需要我们手动的修改一下,比如我们需要将fillColor改为“#FFFFFFFF”这样字体才能显示为白色。并且需要将width和height设置为120dp,否则会有锯齿

SVG的不足之处

矢量图的优点一大把,但也不是万能的。矢量图特别适合icon图标的应用场景,但是不能用于比如加载相册时,设置的placeholder或者error这类需要频繁切换回收的应用场景,否则会造成非常明显的卡顿,因为矢量图是不被硬件加速支持的。

下期预告<<用SVG打造一个绚丽多彩的中国地图>>

阅读更多

近3年BAT面试真题整理合集

一招教你读懂JVM和Dalvik之间的区别

NDK项目实战—高仿360手机助手之卸载监听

分享几个Android很强势的的开源框架

如果有什么问题,欢迎来撩我

SVG前戏—让你的View多姿多彩的更多相关文章

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

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

  2. 学了这么久,vue和微信小程序到底有什么样的区别?

    前言 写了vue项目和小程序,发现二者有许多相同之处,在此想总结一下二者的共同点和区别.相比之下,小程序的钩子函数要简单得多. 一.生命周期 先贴两张图: vue生命周期 小程序生命周期   相比之下 ...

  3. 微信小程序 tp5上传图片

    test.wxml页面 <view class="title">请选择要反馈的问题</view> <view> <picker bindc ...

  4. this.$apply()

    chooseVideo(e) { this.fileInfo = {} let that = this wx.chooseVideo({ sourceType: ['album', 'camera'] ...

  5. 一个实现了View接口的Fragment

    小程序并不新鲜,模式上先有百度轻应用,后有支付宝的各类小服务,再来还有腾讯自家QQ右下角的应用宝:技术上也就是FaceBook RN的那一套.一个技术上无创新,形式上无创意的事物,凭什么勾起了开发者们 ...

  6. 2.1 View的绘制

    view绘制流程是从ViewRoot的performTraversals()方法中开始的,在该方法中会执行view绘制的三部曲,即:measure(测量视图的大小),layout(确定视图的位置)dr ...

  7. SVG 参考手册

    1. SVG元素模块 Animation.Module animate animateColor animateTransform animateMotion set mpath 剪裁模块 clipP ...

  8. SVG 2D入门8 - 文档结构

    前面介绍了很多的基本元素,包括结构相关的组合和重用元素,这里先对SVG的文档结构中剩下的相关元素简单总结一下,然后继续向前领略SVG的其他特性. SVG文档的元素基本可以分为以下几类: 动画元素:an ...

  9. SVG 2D入门6 - 坐标与变换

    坐标系统 SVG存在两套坐标系统:视窗坐标系与用户坐标系.默认情况下,用户坐标系与视窗坐标系的点是一一对应的,都为原点在视窗的左上角,x轴水平向右,y轴竖直向下:如下图所示: SVG的视窗位置一般是由 ...

随机推荐

  1. Docker 创建 mongo 容器

    获取 docker 认证 mongo 镜像: docker pull mongo 创建运行 mongo 容器: docker run -d -it -p : --name mongo3 -m 512M ...

  2. this与回调函数

    在c++里回调函数分2种: 全局函数:不包函在类的内部 或 类内部的静态函数 类内部函数(或叫 局部函数):需要通过实例化后的对象调用的 因c++是c的一层封装,所以类似c里struct内的函数 在传 ...

  3. spring cloud(学习笔记) Enreka服务治理

    服务治理是微服务架构最为核心和基础的模块,主要用来实现各个微服务实例的自动化注册和发现. 记录一下服务注册中心的搭建以及高可用注册中心的实现 1.首先创建两个基础 的spring boot工程,spr ...

  4. python判断小数示例&写入文件内容示例

    #需求分析: #1.判断小数点个数是否为1 #2.按照小数点分隔,取到小数点左边和右边的值 #3.判断正小数,小数点左边为整数,小数点右边为整数 #4.判断负小数,小数点左边以负号开头,并且只有一个负 ...

  5. 使用X.509数字证书加密解密实务(一)-- 证书的获得和管理

    http://www.cnblogs.com/chnking/archive/2007/08/18/860983.html

  6. java实现打印前台页面

    核心:用window自带方法 window.print(); 打印的范围:body里内容,只要在页面能显示出来,都打印 遇到的问题:打印按钮被一起打印出来了,url也别打印出来了 解决办法:在触发打印 ...

  7. mysql存储过程及拼接字符串的用法

    DROP PROCEDURE IF EXISTS insert_historytable;DELIMITER //CREATE PROCEDURE insert_historytable()BEGIN ...

  8. 【tmos】SpringBoot登录拦截

    我的代码 public class WebLoginInterceptor implements HandlerInterceptor { @Autowired private WeixinConfi ...

  9. 基于【字符】操作的IO接口:Writer、Reader

    Reader public class BufferedReaderTest { public static void main(String[] args) throws IOException { ...

  10. Django学习手册 - CURD组件

    CURD CURD是一个数据库技术中的缩写词,一般的项目开发的各种参数的基本功能都是CURD.作用是用于处理数据的基本原子操作. 它代表创建(Create).更新(Update).读取(Retriev ...