矢量图形SVG&高级动画

前言
          SVG,全名Scalable Vector Graphics可伸缩矢量图形,这种图像格式在前端已经是非常广泛了 ,矢量图像: SVG是W3C退出的一种开放标准的文本格式的矢量图形描述语言,他也是基于XML的、专门为网络而设计的图像格式,SVG是一种采用XML来描述而为图形的语言,所以它可以直接打开xml文件来修改和编辑位图图像: 位图图像的存储单位是图像上每一点的像素值,因而文件会比较大,像GIF、JPEG、PNG等都是位图图像格式   

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


Part 1、基本用法
          Vector在Android中指代的是Vector Drawable,也就是Android中的矢量图。Vector图像刚发布的时候,只支持Android5.0+的,自从AppCompat 23.2之后,Vector可以使用于Android2.1以上的所有系统,只需要引用com.android.support:appcompat-v7:23.2.0以上的版本就可以了。但是这里的兼容并非真实的兼容,而是在低版本中生成PNG图片来替代SVG
<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>

tips:

1、android:width/android:height : 矢量图形的大小

2、android:viewportwidth/android:viewportheight : 定义图像被划分的比例大小,例如例子中的500,即把200dp大小的图像划分成500份

Vector Drawable相对于普通的Drawable来说,有以下几个好处:
        (1)Vector图像可以自动进行适配,不需要通过分辨率来设置不同的图片。
        (2)Vector图像可以大幅减少图像的体积,同样一张图,用Vector来实现,可能只有PNG的几十分之一。
        (3)使用简单,很多设计工具,都可以直接导出SVG图像,从而转换成Vector图像 功能强大。

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

下面推荐几个网址

SVG编辑器:http://editor.method.ac/

将SVG文件转化为VectorDrawable xml文件:http://inloop.github.io/svg2android/

众多SVG的图片:http://www.flaticon.com/

效果~

似乎看上去很简单,但当你要使用兼容矢量图的时候需要在build.gradle文件添加

//在gradle2.0及以上:
android {
  defaultConfig {
  vectorDrawables.useSupportLibrary = true
}}
//在gradle 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"
  }
}
这里只能用于AppCompatImageView或者AppCompatImageButton或其子类,而且必须在app:srcCompat标签中,如果你要使用TextView、Button的话就会报错,需要将图片依附于StateListDrawable,InsetDrawable,LayerDrawable,LevelListDrawable,RotateDrawable进行显示

<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
    <item android:drawable="@drawable/chick"/>
</selector>
在23.4.0之后需要手动开启

static {
  AppCompatDelegate.setCompatVectorFromSourcesEnabled(true);
}
这样便能在TextView、Button使用兼容的矢量图了

    <android.support.v7.widget.AppCompatTextView
        android:layout_width="150dp"
        android:layout_height="150dp"
        android:drawableLeft="@drawable/chick"/>
接下来说一下VectorDrawable的性能问题:

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


Part 2、SVG的高级动画

效果~

tips:

1、画出相应图形

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

    <path
        android:name="search"
        android:pathData="M141,17 A9,9 0 1,1 142,16 L149,23"
        android:strokeAlpha="0.8"
        android:strokeColor="#00FF00"
        android:strokeLineCap="round"
        android:strokeWidth="4"/>
    <path
        android:name="bar"
        android:pathData="M0,23 L149,23"
        android:strokeAlpha="0.8"
        android:strokeColor="#7700FF00"
        android:strokeLineCap="square"
        android:strokeWidth="4"/>
</vector>
2、设置animated-vector动画

<animated-vector
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:drawable="@drawable/searchbar">

    <target
        android:name="search"
        android:animation="@animator/anim_searchbar_in"/>

    <target
        android:name="bar"
        android:animation="@animator/anim_searchbar_out"/>

</animated-vector>
这里target的name值指代着图形path的name值

3、为每个path设置动画

anim_searchbar_in

<objectAnimator
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:duration="1000"
    android:propertyName="trimPathStart"
    android:repeatCount="infinite"
    android:repeatMode="reverse"
    android:valueFrom="0"
    android:valueTo="1"
    android:valueType="floatType"/>
anim_searchbar_out

<objectAnimator
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:duration="1000"
    android:propertyName="trimPathStart"
    android:repeatCount="infinite"
    android:repeatMode="reverse"
    android:valueFrom="1"
    android:valueTo="0"
    android:valueType="floatType"/>
效果~

可以仿照上面来定义自己的SVG动画

效果~


tips:

1、定义图形

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

    <group android:name="star_group"
        android:pivotX="200"
        android:pivotY="200"
        android:scaleX="1.0"
        android:scaleY="1.0">

        <path
            android:name="star"
            android:fillColor="#FF00FF"
            android:pathData="M 200.30535,69.729172
            C 205.21044,69.729172 236.50709,141.52218 240.4754,144.40532
            C 244.4437,147.28846 322.39411,154.86809 323.90987,159.53312
            C 325.42562,164.19814 266.81761,216.14828 265.30186,220.81331
            C 263.7861,225.47833 280.66544,301.9558 276.69714,304.83894
            C 272.72883,307.72209 205.21044,268.03603 200.30534,268.03603
            C 195.40025,268.03603 127.88185,307.72208 123.91355,304.83894
            C 119.94524,301.9558 136.82459,225.47832 135.30883,220.8133
            C 133.79307,216.14828 75.185066,164.19813 76.700824,159.53311
            C 78.216581,154.86809 156.16699,147.28846 160.13529,144.40532
            C 164.1036,141.52218 195.40025,69.729172 200.30535,69.729172 z"/>
    </group>
</vector>
这里的group标签的作用:1、对Path进行分组,由于我们后面需要针对Path进行动画,所以可以让具有同样动画效果的Path在同一个Group中。2、拓展动画效果,单个的path标签是没有translateX和translateY属性的,因此无法使用属性动画来控制path translateY,而group标签是有的,所以我们需要先将相关的path标签元素包裹在一个个的group标签中。

2、设置animated-vector动画

<animated-vector xmlns:android="http://schemas.android.com/apk/res/android"
                 android:drawable="@drawable/vd_star" >
    <target
        android:name="star_group"
        android:animation="@animator/star_rotate" />
    <target
        android:name="star"
        android:animation="@animator/star_shap" />
</animated-vector>





评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值