Android SVG 和 VectorDrawable 的基本知识

Android 5.0系统中引入了 VectorDrawable 来支持矢量图(SVG),同时还引入了 AnimatedVectorDrawable 来支持矢量图动画

什么是 SVG ?

SVG是指可伸缩矢量图形 (Scalable Vector Graphics),它不同于传统的位图,不是通过存储图像中每一点的像素值来保存与使用图形,而是通过 XML 文件来定义一个图形,通过一些特定的语法和规则来绘制出我们所需的图像——同样是使用一张图片,SVG 的方式是事先定义好怎么去画这个图,然后等要用的时候再把它去画出来,而使用传统的位图的话就是已经有了画出来的图,然后要用的时候直接把画好的图拿出来用。

  • SVG 是在要用图的时候再把图画出来,所以理所当然的在图片显示的时候会花费更多的时间消耗更多的资源。
  • 同样由于上一个原因, SVG 并不太适合层次过于复杂细节过于繁多的图片。
  • 位图是事先已经画好的图片,所以适应性必然没有 SVG 好,同一张图片在不同分辨率下显示会有差异。
  • SVG 的文件里存储了绘制图片的相关信息,所以我们能够对图片的线条有一个非常清晰的感知,这在做动画的时候特别有用。
  • SVG 没有存储任何图像的像素信息,所以 SVG 的文件体积远小于传统的位图文件。
  • SVG 的文件画出来的图像是矢量图,所以不会存在失真的问题,理论上支持任何级别的缩放。

SVG 和 VectorDrawable 的基本知识 

VectorDrawable 并没有支持所有的 SVG 规范,目前只支持 PathData 和有限的 Group 功能。另外还有一个 clip-path 属性来支持后面绘图的区域。 所以对于使用 VectorDrawable 而言,我们只需要了解 SVG 的 PathData 规范即可(对应自定义控件中的绘图中的Path路径功能)。通过查看 PathData 文档,可以看到 path 数据包含了一些绘图命令,比如 : 

  • moveto 命令 M or m ,移动到新的位置 (大写的命令为绝对坐标命令;小写的命令为相对坐标命令, 下同) ,
  • closepath 命令 Z or z,封闭路径,从当前的位置画一条直线到该路径或者子路径起始位置 
  • lineto 命令 L or l,从当前的位置画一条线到指定的位置 
  • horizontal lineto 命令 H or h,水平画一条直线到指定位置 
  • vertical lineto 命令 V or v,垂直画一条直线到指定位置 
  • quadratic Bézier curve 命令 Q or q ,贝塞尔曲线
  • smooth quadratic Bézier curveto 命令 T  光滑二次贝塞尔曲线
  • elliptical arc  命令 A 椭圆弧

矢量图xml文件

<?xml version="1.0" encoding="utf-8"?>
<vector xmlns:android="http://schemas.android.com/apk/res/android"
    android:width="400dp"
    android:height="400dp"
    android:viewportHeight="400"
    android:viewportWidth="400">
    <path
        android:pathData="M 100 100 L 300 100 L 200 300 z"
        android:strokeColor="#000000"
        android:strokeWidth="5"
        android:fillColor="#FF0000"
        />
</vector>

该示例的画布大小为 400 X 400像素(左上角坐标为0,0; 右下角坐标为400,400), path 路径为: 移动到 100、100 位置,然后画一条线到绝对坐标 300、100位置,然后画一条线到绝对坐标 200、300位置,然后画一条线到该路径的起始位置。这样一个倒三角形就绘制出来了。 

需要注意的是, 在根元素 vector 上有两个宽高设置,其中 viewport 是指矢量图里面的画布大小,而android:width 和 android:height 是指该矢量图所对应的 VectorDrawable 的大小。 
path 元素里面的 pathData 就是矢量图的路径数据,除此之外还可以设置其他属性。

path 元素属性设置说明

svg 路径基本设置

属性设置功能描述
android:name定义该 path 的名字,这样在其他地方可以通过名字来引用这个路径 
android:pathData和 SVG 中 d 元素一样的路径信息。

svg 路径边框相关设置

属性设置功能描述
android:strokeColor定义如何绘制路径边框,如果没有定义则不显示边框 
android:strokeWidth定义路径边框的粗细尺寸 
android:strokeAlpha定义路径边框的透明度  
android:strokeLineCap设置路径线帽的形状,取值为 butt, round, square. 
android:strokeLineJoin设置路径交界处的连接方式,取值为 miter,round,bevel. 
android:strokeMiterLimit设置斜角的上限

当strokeLineJoin设置为 “miter” 的时候, 绘制两条线段以锐角相交的时候,所得的斜面可能相当长。当斜面太长,就会变得不协调。strokeMiterLimit 属性为斜面的长度设置一个上限。这个属性表示斜面长度和线条长度的比值。默认是 10,意味着一个斜面的长度不应该超过线条宽度的 10 倍。如果斜面达到这个长度,它就变成斜角了。当 strokeLineJoin 为 “round” 或 “bevel” 的时候,这个属性无效。 

svg 路径颜色相关设置

属性设置功能描述
android:fillColor定义填充路径的颜色,如果没有定义则不填充路径
android:fillAlpha定义填充路径颜色的透明度 

根元素 vector 

根元素 vector 是用来定义这个矢量图的

基本设置

属性设置功能描述
android:name定义该drawable的名字 
android:width定义该 drawable 的内部(intrinsic)宽度,支持所有 Android 系统支持的尺寸,通常使用 dp 
android:height定义该 drawable 的内部(intrinsic)高度,支持所有 Android 系统支持的尺寸,通常使用 dp 
android:viewportWidth定义矢量图视图的宽度,视图就是矢量图 path 路径数据所绘制的虚拟画布 
android:viewportHeight定义矢量图视图的高度,视图就是矢量图 path 路径数据所绘制的虚拟画布 

附加设置

属性设置功能描述
android:tint定义该 drawable 的 tint 颜色。默认是没有 tint 颜色的 
android:tintMode定义 tint 颜色的 Porter-Duff blending 模式,默认值为 src_in 
android:autoMirrored设置当系统为 RTL (right-to-left) 布局的时候,是否自动镜像该图片。比如 阿拉伯语。 
android:alpha该图片的透明度属性 

group 节点 

有时候我们需要对几个路径一起处理,这样就可以使用 group 元素来把多个 path 放到一起。 group 支持的属性如下: 

属性设置功能描述
android:name定义 group 的名字 
android:rotation定义该 group 的路径旋转多少度 
android:pivotX定义缩放和旋转该 group 时候的 X 参考点。该值相对于 vector 的 viewport 值来指定的。 
android:pivotY定义缩放和旋转该 group 时候的 Y 参考点。该值相对于 vector 的 viewport 值来指定的。 
android:scaleX定义 X 轴的缩放倍数 
android:scaleY定义 Y 轴的缩放倍数 
android:translateX定义移动 X 轴的位移。相对于 vector 的 viewport 值来指定的。 
android:translateY定义移动 Y 轴的位移。相对于 vector 的 viewport 值来指定的。

例如 前面提到的三角形,通过 group 可以把其旋转 90度。

<?xml version="1.0" encoding="utf-8"?>
<vector xmlns:android="http://schemas.android.com/apk/res/android"
    android:width="400dp"
    android:height="400dp"
    android:viewportHeight="400"
    android:viewportWidth="400">
    <group
        android:name="name"
        android:pivotX="200"
        android:pivotY="200"
        android:rotation="90">
        <path
            android:fillColor="#FF0000"
            android:pathData="M 100 100 L 300 100 L 200 300 z"
            android:strokeColor="#000000"
            android:strokeWidth="5" />
    </group>
</vector>

使用创建好的 静态svg 图形

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:orientation="vertical"
    android:layout_width="match_parent"
    android:layout_height="match_parent">
    
    <ImageView
        app:srcCompat="@drawable/triangle"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        tools:ignore="VectorDrawableCompat" />
</LinearLayout>




早起的年轻人 CSDN认证博客专家 移动开发 项目管理 Java
只要用心去做,每一件事情还是有可能成功的,当然成功是没有界限的,只不过是达到自己心里的那个目标,公众号:我的大前端生涯,一个爱喝茶的程序员,通常会搞搞SpringBoot 、Herbinate、Mybatiys、Android、iOS、Flutter、Vue、小程序等.
©️2020 CSDN 皮肤主题: 代码科技 设计师:Amelia_0503 返回首页