Andorid——SVG矢量动画深度学习
Posted 化作孤岛的瓜
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了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
以上是关于Andorid——SVG矢量动画深度学习的主要内容,如果未能解决你的问题,请参考以下文章