SVG—最简单的SVG动画

效果展示


SVG的几个最基础的命令


M:新建起点,参数x,y(M20, 30)
L:连接直线,参数x,y(L30, 20)
H:纵坐标不变,横向连线,参数x(H20)
V:横坐标不变,纵向连线,参数y(V30)
Q:二次贝塞尔曲线,参数x1,y1,x2,y2(Q10,20,30,40)
C:三次贝塞尔曲线,参数x1,y1,x2,y2,x3,y3(C10,20,30,40,50, 60)
Z:连接首尾,闭合曲线,无参数

光看没毛用,画一下。一根线画出来了,3根线也不是问题。(请无视贝塞尔曲线,我目前也不懂)

最基本的一个静态SVG(不含动画)


SVG文件

svg是一个公共标准,下面文件只是android对应的格式,一般我们android猿要获取一个svg文件的渠道是:

  • 网上下。
    http://iconfont.cn/
    这个网站如何用?我是xjb点着点着就会了,无非就是看见图标就点,找download,实在不会网上搜下。

  • 自己画。
    在线画图自定义生成svg:http://editor.method.ac/
    画好了之后,点击网页上的File->save默认保存为svg格式。但这个svg在android是无法使用的。需要下一步的转换。
    普通svg转换为android平台可识别的svg格式:http://inloop.github.io/svg2android/
    点开这个软件中间的区域,会让你选择本地文件,你就选刚刚生成的svg文件,完事之后保存,copy到项目drawAble目录下就能用了。

  • 找有经验的UI做.(UI妹妹表示你一点也不怜香惜玉)

PS:你也可以去下Studio插件里有一个”SVG to VectorDrawable”,这个也能将公共格式的svg转换为android格式的SVG。

这是本文用到SVG文件:


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

    <group
        android:name="rotationGroup"
        android:pivotX="35"
        android:pivotY="35"
        android:rotation="0.0" >

        <path
            android:name="pathchangeGroup"
            android:fillColor="#000000"
            android:pathData=
            "
            M10,10
            L60,10
            L60,20
            L10,20
            Z
            M10,30
            L60,30
            L60,40
            L10,40
            Z
            M10,50
            L60,50
            L60,60
            L10,60
            Z
            " />

    </group>
</vector>

有了这个svg文件,你在xml布局文件内直接当做一个图片资源来用就行了。

<ImageView
        android:id="@+id/img_xjbdraw"
        android:src="@drawable/ic_xjbdraw"
        android:layout_width="200dp"
        android:layout_height="200dp"
        android:layout_centerInParent="true"
        android:scaleType="fitXY" />

但是这么做了之后,并没有动画,这时候我们接下来学习svg动画。

SVG动画


animated-vector

请记得我们刚才在布局文件内的ImageView使用的是这个:android:src="@drawable/ic_xjbdraw",它是一个静态SVG文件,这时候我们需要去定义一个”动态的SVG文件”,即SVG动画,它的根标签是animated-vector


    <animated-vector xmlns:android="http://schemas.android.com/apk/res/android"
        xmlns:tools="http://schemas.android.com/tools"
        android:drawable="@drawable/ic_xjbdraw"
        tools:targetApi="lollipop">

        <target
            android:name="rotationGroup"
            android:animation="@animator/rotation" />

        <target
            android:name="pathchangeGroup"
            android:animation="@animator/pathchange" />

    </animated-vector>

target标签

我们看到这里有俩target标签,他是啥?请看我们一开始show出来的效果图。这个动画的构成是:

  • 360度旋转。
  • 三个平行线合成为一点成为一个箭头。

这里一个target就类似一个动画节点,它挂载一个动画文件,以便让加载这个文件的控件使用依附它的动画。

这里360度旋转我就不说了,他就是一个旋转的属性动画,直接看文件你就明白了。

<!-- rotation.xml -->
<objectAnimator
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:duration="1500"
    android:propertyName="rotation"
    android:valueFrom="0"
    android:valueTo="360" />

另外一个动画,是本文的重点。接下来看它。

同形Path之间的转变


<!-- rotation.xml -->
<set xmlns:android="http://schemas.android.com/apk/res/android">
    <objectAnimator
        android:duration="1500"
        android:propertyName="pathData"
        android:valueFrom="M10,10 L60,10 L60,20 L10,20 Z M10,30 L60,30 L60,40
            L10,40 Z M10,50 L60,50 L60,60 L10,60 Z"
        android:valueTo="M5,35 L40,0 L47.072,7.072 L12.072,42.072 Z M10,30 L60,30 L60,40
            L10,40 Z M12.072,27.928 L47.072,62.928 L40,70 L5,35 Z"
        android:valueType="pathType" />
</set>

pathchange.xml是我本地命名,可以随便取。

可以看到它实际上也是一个属性动画,但是它这里使用的属性值:

android:propertyName=”pathData”
android:valueFrom
android:valueTo
android:valueType=”pathType”

重点是valueFrom,valueTo,它代表将来原本的三天平行直线汇聚成一个箭头。就是对应的字符串值,但是这是有前提的,即——同形Path

何谓同形Path?(摘自https://www.jianshu.com/p/89cfd9042b1e

如果两个path拥有相同的命令数,并且对应位置的命令符相同,那么这两个path我们称之为同形path。
如:
M10,15 L20,20 L25,15 C10,20,20,20,30,10 L50,50 Z
M20,30 L10,10 L15,25 C25,10,30,30,10,20 L35,35 Z

2个注意点

  • 这2个文件需要放在res/animator目录下。否则无法使用属性动画xml标签。
  • animated-vector文件下target标签引用的文件名称是你2个动画文件内定义的android:propertyName名称

最后再代码内使用

  • 将之前引用的静态vector替换掉
  • 动画的启动

 <ImageView
        android:id="@+id/img_xjbdraw"
        android:src="@drawable/animvectordrawable"
        android:layout_width="200dp"
        android:layout_height="200dp"
        android:layout_centerInParent="true"
        android:scaleType="fitXY" />

 ↓

ImageView xjbDrawImg = findViewById(R.id.img_xjbdraw);
AnimatedVectorDrawable animatedVectorDrawable = (AnimatedVectorDrawable) xjbDrawImg.getDrawable();
animatedVectorDrawable.start();
// 加载SVG
//        anim1 = (AnimatedVectorDrawable) getResources().getDrawable(R.drawable.anim1);  anim1.start();
//        anim2 = (AnimatedVectorDrawable) getResources().getDrawable(R.drawable.anim2);  anim2.start();
//        anim3 = (AnimatedVectorDrawable) getResources().getDrawable(R.drawable.anim3);  anim3.start();

本文到此结束,但涉及的深度还是太浅,下一篇将进一步研究SVG动画。有错误请直接指出,感谢。

Demo


https://github.com/zj614android/Svg-/tree/master/svg1

Reference


Android高级动画(2):https://www.jianshu.com/p/89cfd9042b1e
Android高级动画(3):https://www.jianshu.com/p/d6cc8d218900
Android使用矢量图(SVG, VectorDrawable)实践篇:https://www.jianshu.com/p/0555b8c1d26a
手把手教学, android 使用 SVG:https://www.jianshu.com/p/5c81970ddf33
Android Study 之 聊聊有关SVG那些事儿:https://blog.csdn.net/u012400885/article/details/78956947
PathView案例:https://blog.csdn.net/crazy__chen/article/details/47728241

猜你喜欢

转载自blog.csdn.net/user11223344abc/article/details/81207488
SVG