Andorid——SVG矢量动画深度学习(一)

概览:

本文主要描述了Android系统实现矢量动画的各种方式以及基础应用,也是一个月以来对矢量动画的学习和总结.

矢量图:

矢量图不同于位图是用像素描述图像的,它是用数学曲线描述图形。所以一张图片就是对应着一系列的数学曲线,所以图片的显示尺寸和图片体积无关。(这里为什么说显示尺寸,因为矢量图根本就没有所谓的尺寸,就看你把它显示成多大),它的体积就是文本文件的大小。并且矢量图可以无限拉伸不失真。

在 Android 5.0 ( API 21) 时候,用 VectorDrawable 支持矢量图,用 AnimatedVectorDrawable 支持矢量图动画。 Vector Drawable 在 XML 中是以 < Vector > 标签定义,主要由以下三个标签构成:

1.< path > 是绘制几何图形的轮廓

2.< group > 是定义变换的细节

3.< clip-path > 是定义裁剪的区域

 具体的绘制可参考并练习一遍:https://blog.csdn.net/zwlove5280/article/details/73196543

矢量动画:

矢量动画主要是由animator资源文件夹下的objectAnimator文件定义,通过propertyName制定动画类型

1.普通属性动画(旋转,平移,透明度等)使用animated-vector实现:主要分为三个步骤

(1).在drawable中创建一个animated-vector文件资源文件,avdvector.xml:

<?xml version="1.0" encoding="utf-8"?>
<!--avd_check.xml-->
<animated-vector xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:drawable="@drawable/avd_check"
    tools:targetApi="lollipop">
    <target
        android:name="rotationGroup"
        android:animation="@animator/rotation_around" />
    <target
        android:name="check"
        android:animation="@animator/stroke_color_animator" />
    <target
        android:name="check"
        android:animation="@animator/alpha_animator" />
</animated-vector>
avd_check.xml 打钩矢量图文件:
<?xml version="1.0" encoding="utf-8"?><!--vd_check.xml--><!--vd_check.xml-->
<vector xmlns:android="http://schemas.android.com/apk/res/android"
    android:width="100dp"
    android:height="100dp"
    android:viewportWidth="24"
    android:viewportHeight="24">
    <group
        android:name="rotationGroup"
        android:pivotX="12"
        android:pivotY="12"
        android:rotation="0">
        <path
            android:name="check"
            android:pathData="M4 10 L9 16 L20 4"
            android:strokeWidth="1"
            android:strokeAlpha="1.0"
            android:strokeColor="@color/colorPrimary"
            android:strokeLineCap="round" />
    </group>
</vector>

(2).分别在animator中实现target定义的动画类:

rotation_around.xml
<?xml version="1.0" encoding="utf-8"?>
<!--/res/animator/rotation_round.xml-->
<objectAnimator xmlns:android="http://schemas.android.com/apk/res/android"
    android:duration="1000"
    android:propertyName="rotation"
    android:valueFrom="0"
    android:valueTo="360" />

stroke_color_animator.xml
<?xml version="1.0" encoding="utf-8"?>
<!--/res/animator/alpha_animator.xml-->
<set xmlns:android="http://schemas.android.com/apk/res/android"
    android:ordering="sequentially">
    <objectAnimator
        android:duration="500"
        android:propertyName="strokeAlpha"
        android:valueFrom="1f"
        android:valueTo="0f" />
    <objectAnimator
        android:duration="500"
        android:propertyName="strokeAlpha"
        android:valueFrom="0f"
        android:valueTo="1f" />
</set>

alpha_animator.xml
<?xml version="1.0" encoding="utf-8"?>
<!--res/animator/stroke_color_animator.xml-->
<objectAnimator xmlns:android="http://schemas.android.com/apk/res/android"
    android:propertyName="strokeColor"
    android:valueFrom="@color/colorAccent"
    android:valueTo="@color/colorPrimary"
    android:duration="1000"/>

(3).在image中设置avdvector为drawable,并在点击事件中设置:

Animatable vectorD = (Animatable) img_check.getDrawable();
                vectorD.start();

效果如图:

2.使用trimPath 实现路径进度裁剪矢量动画 (注意是只能绘制单一线段,如果需要绘制两段,需要做两段动画) :

(1).定义路径动画的animated-vector文件avdvctortrim.xml

<?xml version="1.0" encoding="utf-8"?><!--avd_check.xml-->
<animated-vector xmlns:android="http://schemas.android.com/apk/res/android"
    android:drawable="@drawable/avd_check">
    <target
        android:name="check"
        android:animation="@animator/trim_path_animator" />
</animated-vector>

(2).定义路径文件:trim_path_animator.xml

<?xml version="1.0" encoding="utf-8"?><!--trim_path_animator.xml-->
<objectAnimator xmlns:android="http://schemas.android.com/apk/res/android"
    android:duration="1500"
    android:interpolator="@android:interpolator/linear"
    android:propertyName="trimPathEnd"
    android:valueFrom="0.0"
    android:valueTo="1.0"
    android:valueType="floatType" />

(3).代码调用的方法同上,直接上效果图:

3.使用pathData 实现path变幻矢量动画(即从一个矢量图变化到另一个矢量图,注意这里的变化并不是单纯变化,而是一种路径动画,特别酷炫)

(1).定义变化的animated-vector文件avd_cross2check.xml

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

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

    <target android:name="cross">
        <aapt:attr name="android:animation">
            <objectAnimator xmlns:android="http://schemas.android.com/apk/res/android"
                android:duration="1500"
                android:interpolator="@android:interpolator/fast_out_slow_in"
                android:propertyName="pathData"
                android:valueFrom="@string/cross_path"
                android:valueTo="@string/check_path"
                android:valueType="pathType" />
        </aapt:attr>
    </target>
</animated-vector>

注意到这里<target>标签下可以直接写animation。

十字架的资源文件夹:avd_cross.xml

<?xml version="1.0" encoding="utf-8"?><!--vd_circle.xml-->
<vector xmlns:android="http://schemas.android.com/apk/res/android"
    android:width="100dp"
    android:height="100dp"
    android:viewportWidth="24"
    android:viewportHeight="24">
    <group
        android:name="rotationGroup"
        android:pivotX="12"
        android:pivotY="12"
        android:rotation="0">
        <path
            android:name="cross"
            android:pathData="@string/cross_path"
            android:strokeWidth="1"
            android:strokeAlpha="1.0"
            android:strokeColor="@color/colorPrimary"
            android:strokeLineCap="round" />
    </group>

</vector>

旋转的资源文件:rotation.xml

<?xml version="1.0" encoding="utf-8"?>
<objectAnimator
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:duration="1500"
    android:propertyName="rotation"
    android:valueFrom="0"
    android:valueTo="360" />

这里要注意,target里的name要对应drawable里group或者path的name才会起作用,不然会报错。

调用方式一样,效果如下:

4.使用animated-selector实现矢量图来回切换的效果,上面的第三点只实现了单向切换,也就是说不能变回来。但是用animated-selector可以实现状态判断与切换。

(1).定义animated-selector文件asl_check.xml:

<?xml version="1.0" encoding="utf-8"?>
<animated-selector xmlns:android="http://schemas.android.com/apk/res/android">
    <item
        android:id="@+id/check"
        android:drawable="@drawable/avd_check"
        android:state_checked="true" />
    <item
        android:id="@+id/cross"
        android:drawable="@drawable/avd_cross"
        android:state_checked="false" />

    <transition
        android:drawable="@drawable/avd_check2cross"
        android:fromId="@id/check"
        android:toId="@id/cross" />

    <transition
        android:drawable="@drawable/avd_cross2check"
        android:fromId="@id/cross"
        android:toId="@id/check" />
</animated-selector>

 其中check和cross分别是打钩和十字架的矢量图,通过android:state_checked分别定义了它们的状态属性。

transition标签标明了转换过程以及使用到的矢量动画animated-vector资源文件。

(2)创建两种过程的资源文件:

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

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

    <target
        android:name="check"
        android:animation="@animator/path_animator" />
</animated-vector>

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

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

    <target android:name="cross">
        <aapt:attr name="android:animation">
            <objectAnimator xmlns:android="http://schemas.android.com/apk/res/android"
                android:duration="1500"
                android:interpolator="@android:interpolator/fast_out_slow_in"
                android:propertyName="pathData"
                android:valueFrom="@string/cross_path"
                android:valueTo="@string/check_path"
                android:valueType="pathType" />
        </aapt:attr>
    </target>
</animated-vector>

(3).OnclickListner代码中调用:

   isCheckSelect = !isCheckSelect;
                final int[] stateSet = {android.R.attr.state_checked * (isCheckSelect ? 1 : -1)};
                img_animselector.setImageState(
                        stateSet, true);

这里的isCheckSelect是自己定义的初始状态值。

效果如下:

可以看到实现了自由的切换~

下一篇博客会手动实现矢量切换的动画效果(不通过Andorid系统的xml方式,纯代码实现坐标转换),欢迎各位大佬萌新留言或者私信交流~!

代码下载地址:

点我下载

参考:

https://www.jianshu.com/p/89cfd9042b1e

https://www.jianshu.com/p/00f1f6bb96b3  

发布了70 篇原创文章 · 获赞 75 · 访问量 27万+

猜你喜欢

转载自blog.csdn.net/qq_22770457/article/details/94485505