Android SVG

SVG简介

SVG:即Scalable Vector Graphics 可伸缩矢量图形,这种图像格式在前端中已经使用的非常广泛了。因SVG是矢量图形,而且伸缩不会损失质量,微信也使用SVG技术,可见SVG的优势多么强大。

在W3C对SVG的介绍是:SVG 是使用 XML 来描述二维图形和绘图程序的语言。

上面中提到SVG是矢量图,那么什么是矢量图呢?它和位图有什么不同?

1)、矢量图像:SVG是W3C 推出的一种开放标准的文本式矢量图形描述语言,他是基于XML的、专门为网络而设计的图像格式。SVG是一种采用XML来描述二维图形的语言,所以它可以直接打开xml文件来修改和编辑。

2)、位图图像:位图图像的存储单位是图像上每一点的像素值,因而文件会比较大,像GIF、JPEG、PNG等都是位图图像格式。

Android中的矢量图

矢量图在Android中使用Vector Drawable表示,在AS中我们可以通过新建一个Vector asset得到矢量图。

AS中为Vector提供了大量的矢量制作图形

同样开发者可以选择local file选择本地的SVG和PNG图片来制作。最终生成一个xml文件。

注意:

1、Vector图像刚发布的时,只支持Android 5.0+的,自从AppCompat 23.2之后,Vector可以使用于Android 2.1以上的所有系统。

2、使用时只需要引用com.android.support:appcompat-v7:23.2.0以上的版本就可以了。 其实所谓的兼容也是个坑爹的兼容,即低版本并非真实使用SVG,而是生成PNG图片。

Vector Drawable优点:

(1)Vector图像可以自动进行适配,不需要通过分辨率来设置不同的图片。

(2)Vector图像可以大幅减少图像的体积,同样一张图,用Vector来实现,可能只有PNG的几十分之一。

(3)使用简单,很多设计工具,都可以直接导出SVG图像,从而转换成Vector图像 功能强大。

(4)不用写很多代码就可以实现非常复杂的动画 成熟、稳定,前端已经非常广泛的进行使用了。

Vector 语法简介

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

M = moveto(M X,Y) :将画笔移动到指定的坐标位置,相当于 android Path 里的moveTo(),’M’处理时,只是移动了画笔, 没有画任何东西;

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():关闭路径(会自动绘制链接起点和终点);

使用上面的指令时,需要注意以下几点:

1)坐标以(0,0)为中心,X轴水平向右,Y轴水平向下

2)所有指令大小写均可,大写绝对定位,参照全军坐标系;小写相对定位,参照父容器坐标系。

3)指令和数据间的空格可以省略

4)同一指令出现多次可以只用一次。

SVG常用指令

L:绘制直线的指令是L,代表从当前点绘制直线到给定点,“L”之后的参数是一个点坐标,如"L 200 400"绘制直线,同时还可以使用H和V指令来绘制水平、竖直线,后面的参数是x坐标(H指令)或y坐标(V指令)。

M:类似Android绘图中的path类的moveTo方法,即代表将画笔移动到某一点,但并不发生绘制动作。

A:绘制一段弧线,且允许弧线不闭合。可以把A指令绘制的弧线想象成是椭圆的某一段,A指令有以下七个函数:

1)RX,RY指所在椭圆的半轴大小;

2)XROTATION指椭圆的X轴与水平方向顺时针方向的夹角,可以想象成一个水平的椭圆绕中心点顺时针旋转XROTATION的角度;

3)FLAG1只有两个值,1表示大角度弧线,0表示小角度弧线;

4)FLAG2只有两个值,确定从七点至终点的方向,1为顺时针,0为逆时针;

5)X、Y轴为终点坐标。

SVG编辑器

关于上面的SVG的语法,开发者不必全部精通,一般熟悉即可,而且这些path标签和数据可以交给SVG编辑器来实现,如:http://editor.method.ac/,也可以下载离线的SVG编辑器,如Inkscape。

使用SVG编辑器得到SVG,然后使用http://inloop.github.io/svg2android/生成VectorDrawable 的xml代码。

除了以上的方法得到SVG,AndroidStudio本身也集合了SVG的插件(即上面所讲的Android中的矢量图),使用插件时,AS自动生成兼容性的图片。

除了AS中提供大量的SVG资源,一些网站同样提供了非常多的SVG给我们使用,如设计达人Free Vector Icons

静态Vector图像

静态的Vector比较生硬,比如我们使用AS生成的VectorDrawable 。

<vector xmlns:android="http://schemas.android.com/apk/res/android"
        android:width="24dp"
        android:height="24dp"
        android:viewportWidth="24.0"
        android:viewportHeight="24.0">
    <path
        android:fillColor="#FF000000"
        android:pathData="M20,11H7.83l5.59,-5.59L12,4l-8,8 8,8 1.41,-1.41L7.83,13H20v-2z"/>
</vector>
复制代码

vector标签包含两组宽高属性width、height、viewportHeight、viewportWidth,他们具有不同的含义。 width、height:SVG图像的具体大小 viewportHeight、viewportWidth:定义图像被划分的比例大小,例如例子中的400,即把24dp大小的图像划分成400份,后面Path标签中的坐标,就全部使用的是这里划分后的坐标系统。这样做有一个非常好的作用,就是将图像大小与图像分离,后面可以随意修改图像大小,而不需要修改PathData中的坐标。

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

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
    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:layout_width="match_parent"
    android:padding="20dp"
    android:layout_height="match_parent"
    tools:context="com.main.svg.SVGActivity">
    <ImageView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:background="@drawable/ic_method_draw_image"/>
</RelativeLayout>
复制代码

动态Vector

有静态的Vector,就有动态的Vector,动态Vector才是Android Vector Drawable的精髓所在。

在Android5.0以上,Google引入了大量的线图动画,页面发生改变,icon不再生硬地切换。如下面这组:

这是Android打开抽屉时页面的icon动画,相信很多读者看过,这就是通过动态的Vector来实现的。 实现动态Vector步骤: 1)绘制静态的VectorDrawable

<?xml version="1.0" encoding="utf-8"?>
<vector xmlns:android="http://schemas.android.com/apk/res/android"
        android:width="24dp"
        android:height="24dp"
        android:viewportHeight="24"
        android:viewportWidth="24">

    <path
        android:fillColor="#FFFFFFFF"
        android:pathData="M16 1L4 1C2.9 1 2 1.9 2 3L2 17 4 17 4 3 16 3Z"/>
    <group android:name="sheet">
        <path
            android:fillColor="#FFFFFFFF"
            android:pathData="M19 5L8 5C6.9 5 6 5.9000001 6 7.0000001L6 21c0 1.1 0.9 2 2 2l11 0c1.1 0 2 -0.9 2 -2L21 7.0000001C21 5.9000001 20.1 5 19 5Zm0 16l-11 0 0 -13.9999999 11 0z"/>
    </group>

</vector>
复制代码

2)编写变换的属性动画

<?xml version="1.0" encoding="utf-8"?>
<set
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:duration="300"
    android:fillAfter="true">

    <objectAnimator
        android:duration="300"
        android:propertyName="translateX"
        android:repeatCount="1"
        android:repeatMode="reverse"
        android:valueFrom="0"
        android:valueTo="-4"
        android:valueType="floatType"/>
    <objectAnimator
        android:duration="300"
        android:propertyName="translateY"
        android:repeatCount="1"
        android:repeatMode="reverse"
        android:valueFrom="0"
        android:valueTo="-4"
        android:valueType="floatType"/>
</set>
复制代码

3)使用AnimatedVectorDrawable将VectorDrawable和ObjectAnimator粘合在一起

<?xml version="1.0" encoding="utf-8"?>
<animated-vector
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:drawable="@drawable/a">

    <target
        android:name="sheet"
        android:animation="@anim/aa">
    </target>
</animated-vector>
复制代码

这里的target的android:name必须和作用的group的android:name命名一致。

4)启动动画

private void starAnim() {

        Drawable drawable = icon.getDrawable();
        if (drawable instanceof Animatable){
            ((Animatable) drawable).start();
        }
    }
复制代码

以上就是实现动态的Vector过程。

VectorDrawable的性能

VectorDrawable的性能问题:

1)Bitmap的绘制效率并不一定会比Vector高,它们有一定的平衡点,当Vector比较简单时,其效率是一定比Bitmap高的,所以,为了保证Vector的高效率,Vector需要更加简单,PathData更加标准、精简,当Vector图像变得非常复杂时,就需要使用Bitmap来代替了;

2)Vector适用于ICON、Button、ImageView的图标等小的ICON,或者是需要的动画效果,由于Bitmap在GPU中有缓存功能,而Vector并没有,所以Vector图像不能做频繁的重绘;

3)Vector图像过于复杂时,不仅仅要注意绘制效率,初始化效率也是需要考虑的重要因素;

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值