Android自定义动画三-SVG动画

本篇文章主要是对SVG的一个介绍和使用,以及Android中对SVG的一个支持,从而可以帮助我们在android下很轻松的通过SVG实现一些非常酷炫的动画效果。

1.SVG介绍

SVG 是使用 XML 来描述二维图形和绘图程序的语言。

它具备以下的特点:
- SVG 指可伸缩矢量图形 (Scalable Vector Graphics)
- SVG 用来定义用于网络的基于矢量的图形
- SVG 使用 XML 格式定义图形
- SVG 图像在放大或改变尺寸的情况下其图形质量不会有所损失
- SVG 是万维网联盟的标准
- SVG 与诸如 DOM 和 XSL 之类的 W3C 标准是一个整体

用户可以直接用代码来描绘图像,可以用任何文字处理工具打开SVG图像,通过改变部分代码来使图像具有交互功能,并可以随时插入到HTML中通过浏览器来观看。

2.SVG 的历史和优势

在 2003 年一月,SVG 1.1 被确立为 W3C 标准。
参与定义 SVG 的组织有:太阳微系统、Adobe、苹果公司、IBM 以及柯达。
与其他图像格式相比,使用 SVG 的优势在于:
- SVG 可被非常多的工具读取和修改(比如记事本)
- SVG 与 JPEG 和 GIF 图像比起来,尺寸更小,且可压缩性更强。
- SVG 是可伸缩的
- SVG 图像可在任何的分辨率下被高质量地打印
- SVG 可在图像质量不下降的情况下被放大
- SVG 图像中的文本是可选的,同时也是可搜索的(很适合制作地图)
- SVG 可以与 Java 技术一起运行
- SVG 是开放的标准
- SVG 文件是纯粹的 XML
- SVG 的主要竞争者是 Flash。

与 Flash 相比,SVG 最大的优势是与其他标准(比如 XSL 和 DOM)相兼容。而 Flash 则是未开源的私有技术。

3.Android使用SVG动画

从上诉的描述中可以看到SVG是一个可伸缩的矢量图,而且相较于JPG和GIF图像尺寸都要更小,并且可以直接在xml中写入。正式由于这样的特点,那么 Android 从 5.0 提供了新的API VectorDrawable,通过该对象,我们可以使用矢量图SVG,在编写xml文件中,通过关键的几个标签节点vector,animated-vector,path完成对SVG的编写以及动画的实现。

VectorDrawable

可以看到 VectorDrawable 是继承与Drawable,并且官网说明了是用于创建一个drawable通过XML文件中申明根节点 vector 来实现一个android下的矢量图。

VectorDrawable 的出现也意味着以前我们放在mdpi, hdpi, xhdpi, xxhdpi中的部分图片资源(适合用矢量图描述的,比如图标)只用一个VectorDrawable 替代就可以了。

在vector节点下我们可以使用 “group、clip-path、path” 来描述一个drawable图形;“group”节点定义一组path或者子group,而path元素定义需要绘制的路径。clip-path节点定义当前绘制的剪切路径。注意,clip-path 只对当前的 group 和子 group 有效。

接下来大家可以通过以下的代码来学习VectorDrawable的定义:

<?xml version="1.0" encoding="utf-8"?>
<vector xmlns:android="http://schemas.android.com/apk/res/android"android:width="200dp"android:height="200dp"android:viewportHeight="100"android:viewportWidth="100"><!--这里的viewportHeight:100的意思是将高度分为了100份这里的viewportWidth:100的意思是将宽度分为了100份--><group><pathandroid:name="path1"android:pathData="M 20,80L 50,80 80,80"android:strokeColor="@android:color/holo_green_dark"android:strokeLineCap="round"android:strokeWidth="5"/><pathandroid:name="path2"android:pathData="M 20,20L 50,20 80,20"android:strokeColor="@android:color/holo_green_dark"android:strokeLineCap="round"android:strokeWidth="5"/></group>
</vector>

这段代码就是在Res下的drawable目录下建立了一个 xml 文件,然后指定根节点为 vector 写出的两根线段的效果。效果图如下:

上述代码中就是定义了一个 group 包含了两个path,而这两个 path 分别代表一根直线的绘制。这里要重点去理解的是 path 节点下的 pathData属性。

PATH命令

以下这些命令用于路径数据:

M = moveto(M X,Y):将画笔移动到指定的坐标位置,但未发生绘制L = lineto(L X,Y):画直线到指定的坐标位置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 curveto(Q X,Y,ENDX,ENDY):二次贝塞曲线T = smooth quadratic Belzier curveto(T ENDX,ENDY):映射前面路径后的终点A = elliptical Arc(A RX,RY,XROTATION,FLAG1,FLAG2,X,Y):弧线Z = closepath():关闭路径

注释:以上所有命令均允许小写字母。大写表示绝对定位,小写表示相对定位。

对于做 Android 开发的我们来说要掌握这么多命令,并且如果需要绘制一个比较复杂的图形那么可能 pathData中需要写很多的数据,这肯定不是我们想看到的结果,比如下面的这个效果:

对应的SVG代码为:

<?xml version="1.0" encoding="iso-8859-1"?>
<!-- Generator: Adobe Illustrator 19.0.0, SVG Export Plug-In . SVG Version: 6.00 Build 0)  -->
<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"viewBox="0 0 490.358 490.358" style="enable-background:new 0 0 490.358 490.358;" xml:space="preserve">
<g><g><circle style="fill:#3C92CA;" cx="166.658" cy="164.129" r="137.1"/><path d="M490.358,377.629c0-0.3,0-0.6-0.1-0.9c0-0.3-0.1-0.6-0.2-0.9s-0.1-0.6-0.2-0.8c-0.1-0.3-0.2-0.5-0.4-0.8c-0.1-0.3-0.2-0.5-0.4-0.8c-0.1-0.3-0.3-0.5-0.5-0.7s-0.3-0.5-0.5-0.7s-0.4-0.4-0.7-0.6c-0.2-0.2-0.4-0.4-0.6-0.6s-0.5-0.3-0.8-0.5c-0.2-0.1-0.4-0.3-0.7-0.4l-110.3-54.4c-0.3-0.2-0.6-0.3-1-0.4c-1.9-0.7-47.4-16.6-84.6,0.1l-82.1,29.7c-0.2,0.1-0.5,0.2-0.7,0.3c-11.8,5.4-18,17.5-15.5,30.2c2.5,12.6,12.7,21.5,25.5,22.1c0.1,0,0.1,0,0.2,0c0.8,0,4.4-0.2,41.8-2.6c16.3-1,33.1-2.1,34.6-2.2c4.7-0.2,8.6-4,8.7-8.8c0.1-5-3.8-9.2-8.9-9.3c-0.5,0-0.5,0-35.5,2.2c-17.5,1.1-37.1,2.4-40.4,2.6c-6.3-0.5-7.8-5.8-8.2-7.4c-0.7-3.4,0.3-7.9,5-10.2l82-29.7c0.2-0.1,0.4-0.2,0.7-0.3c28.8-13.1,66.4-1.3,70.9,0.1l49.1,24.2l-27,63.7c-13.3-8.2-29.5-10.4-44.5-5.9l-110.2,33.1c-13.1,4-27.6,2.5-39.7-4.1l-172.6-93.5c-6.2-3.4-4.2-9.3-3.7-10.5c0.6-1.6,3.2-6.6,9.5-4.9l134.1,44.7c4.7,1.6,9.9-1,11.5-5.7c1.6-4.8-1-9.9-5.7-11.5l-134.4-44.9c-0.2-0.1-0.3-0.1-0.5-0.1c-13.3-3.6-26.2,2.8-31.3,15.6c-5.2,12.9-0.3,26.5,11.9,33.2l172.7,93.8c16.3,8.9,35.8,10.9,53.5,5.5l110.2-33.1c10.1-3,21-1.6,29.9,4.1l56.2,35.4c0.3,0.2,0.5,0.3,0.8,0.4c0.1,0,0.1,0.1,0.2,0.1h0.1c0.1,0.1,0.2,0.1,0.4,0.1c0.2,0.1,0.5,0.2,0.7,0.3c0.1,0,0.3,0.1,0.4,0.1c0.2,0.1,0.5,0.1,0.7,0.2c0.1,0,0.3,0,0.4,0.1c0.4,0,0.7,0.1,1.1,0.1l0,0l0,0l0,0l0,0c0.4,0,0.8,0,1.2-0.1c0.1,0,0.3,0,0.4-0.1c0.3,0,0.5-0.1,0.8-0.2c0.1,0,0.3-0.1,0.4-0.1c0.2-0.1,0.5-0.2,0.7-0.3c0.1-0.1,0.3-0.1,0.4-0.2c0.2-0.1,0.4-0.2,0.7-0.4c0.1-0.1,0.3-0.2,0.4-0.2c0.2-0.1,0.4-0.3,0.6-0.4c0.1-0.1,0.3-0.2,0.4-0.3c0.2-0.2,0.3-0.3,0.5-0.5c0.1-0.1,0.2-0.2,0.4-0.4c0.2-0.2,0.3-0.4,0.4-0.6c0.1-0.1,0.2-0.3,0.3-0.4c0,0,0-0.1,0.1-0.1c0-0.1,0.1-0.2,0.1-0.2c0.1-0.2,0.3-0.5,0.4-0.8l40-85.2c0.1-0.3,0.2-0.5,0.3-0.8c0.1-0.3,0.2-0.6,0.3-0.8c0.1-0.3,0.1-0.6,0.1-0.9s0.1-0.6,0.1-0.9C490.358,378.229,490.358,377.929,490.358,377.629z M469.358,382.229l-31.9,67.9l-32.3-20.4l27.7-65.4L469.358,382.229z"/><path d="M153.858,173.229h25.4c10.4,0,18.8,8.4,18.8,18.8c0,10.4-8.4,18.8-18.8,18.8h-45.7c-5,0-9.1,4.1-9.1,9.1s4.1,9.1,9.1,9.1h23.9v17.9c0,5,4.1,9.1,9.1,9.1s9.1-4.1,9.1-9.1v-17.9h3.7c20.4,0,37-16.6,37-37s-16.6-37-37-37h-25.4c-10.4,0-18.8-8.4-18.8-18.8s8.4-18.8,18.8-18.8h44.9c5,0,9.1-4.1,9.1-9.1s-4.1-9.1-9.1-9.1h-23.1v-17.5c0-5-4.1-9.1-9.1-9.1s-9.1,4.1-9.1,9.1v17.6h-3.7c-20.4,0-37,16.6-37,37C116.958,156.629,133.558,173.229,153.858,173.229z"/><path d="M166.658,310.229c80.6,0,146.1-65.6,146.1-146.1s-65.6-146.2-146.1-146.2s-146.2,65.6-146.2,146.2S86.058,310.229,166.658,310.229z M166.658,36.129c70.6,0,128,57.4,128,128s-57.4,128-128,128s-128-57.4-128-128S96.058,36.129,166.658,36.129z"/></g>
</g>
</svg>

对于这么庞大的数据计算我们肯定是不可能去手动画的,而这张图片也是我从 FLATICON 网站上随便找的一张 SVG 图片,down下来就是现成的 svg 文件了,我们可以直接使用到我们android 中来,所以以后开发中可以让 UI 给我们这样的 SVG 文件就行了,当然也有 SVG编辑工具直接产出一些好看的 SVG图片,都可以在 http://www.flaticon.com中找到。

AnimatedVectorDrawable

AnimatedVectorDrawable 同样继承 Drawable,不过它实现了 Animatable 接口,专门用于让 VectorDrawable 动起来。

首先来看官方的说明:

This class animates properties of a VectorDrawable with animations defined using ObjectAnimator or AnimatorSet.Starting from API 25, AnimatedVectorDrawable runs on RenderThread (as opposed to on UI thread for earlier APIs). This means animations in AnimatedVectorDrawable can remain smooth even when there is heavy workload on the UI thread. Note: If the UI thread is unresponsive, RenderThread may continue animating until the UI thread is capable of pushing another frame. Therefore, it is not possible to precisely coordinate a RenderThread-enabled AnimatedVectorDrawable with UI thread animations. Additionally, onAnimationEnd(Drawable) will be called the frame after the AnimatedVectorDrawable finishes on the RenderThread.AnimatedVectorDrawable can be defined in either three separate XML files, or one XML.

AnimatedVectorDrawable 通过 ObjectAnimator 或 AnimatorSet 对 VectorDrawable 的某个属性作动画。

从API-25开始,AnimatedVectorDrawable 运行在 RenderThread (相反地,早期API是运行在UI线程)。这也就是说 AnimatedVectorDrawable 在UI线程繁忙时也能保持流畅运行。

如果UI线程没有反应,RenderThread 会持续动画计算,直到UI线程有能力推进下一帧。因此,没有办法准确地同步 RenderThread-enabled 的 AnimatedVectorDrawable 和 UI 线程中的 Animations。此外, Animatable2.AnimationCallback.onAnimationEnd(drawable) 肯定会在 RenderThread 渲染完 AnimatedVectorDrawable 最后一帧时被调用。

Animated vector drawable 可以让 group 和 path 元素的属性动态变化。group 定义一组 path 或者子 group,而 path 元素定义需要绘制的路径。当你想让 VectorDrawable 呈现动画效果,在定义 VectorDrawable 的时候需要为 group 和 path 的 android:name 属性设置一个唯一的名字,以便在Animated vector drawable中找到它们。比如在上面我们画的两根直线demo,我现在想让两根直线做出以下的动画效果:

在上面的两根直线 vector 代码中是由两段 path 定义出来的,也分别定义了 name 分别为 path1 path2,所以接下来只需要定义一个 AnimatedVectorDrawable 来分别执行这两段 path的动画。

代码如下:

<?xml version="1.0" encoding="utf-8"?>
<animated-vector xmlns:android="http://schemas.android.com/apk/res/android"android:drawable="@drawable/two_line"><targetandroid:animation="@animator/anim_path1"android:name="path1"/><targetandroid:animation="@animator/anim_path2"android:name="path2"/></animated-vector>

注意上面:
一般我们使用 propertyName 节点都是传入基本动画(平移,缩放,旋转,透明度)
此处传入的为:pathData,效果为让动画沿着设定的 valueFrom 和 valueTo 的数据执行
最后要加入节点 android:valueType=”pathType”,表示数据类型为 path 类型,否则会报错

在 target 标签中需要分别为当前你要执行的 path 指定一个 属性动画,比如 anim_path1,代码如下:(必须是属性动画,所以在 animator 下创建)

<?xml version="1.0" encoding="utf-8"?>
<objectAnimator  xmlns:android="http://schemas.android.com/apk/res/android"android:duration="500"android:propertyName="pathData"android:interpolator="@android:interpolator/bounce"android:valueFrom="M 20,80L 50,80 80,80"android:valueTo="M 20,80L 50,50 80,80"android:valueType="pathType">
</objectAnimator >

anim_path2的代码也是类似:

<?xml version="1.0" encoding="utf-8"?>
<objectAnimator  xmlns:android="http://schemas.android.com/apk/res/android"android:duration="500"android:propertyName="pathData"android:interpolator="@android:interpolator/bounce"android:valueFrom="M 20,20L 50,20 80,20"android:valueTo="M 20,20L 50,50 80,20"android:valueType="pathType">
</objectAnimator >

这里还分别给两个动画指定了一个动画插值器:bounce,使合并的时候具有碰撞效果。

输入框SVG背景动画

最后再来一个输入框的背景动画,效果如下:


结合svg动画和基本逻辑代码实现EditText的输入特效
在 activity 主界面中准备一个 ImageView 和两个 EditText ,第一个 EditText 没有背景(后续将为 ImageView 设置图片来使得 EditText 看起来像有一个背景一样),第二个 EditText 存在默认背景

这里直接贴出主要的 vector 和 animated_vector 代码,更详细的代码,请到GitHUb下载查看:https://github.com/zphuanlove/AnimationProject

首先是输入框背景,一根直线和一个对勾的代码:

<?xml version="1.0" encoding="utf-8"?>
<vector xmlns:android="http://schemas.android.com/apk/res/android"android:width="300dp"android:height="96dp"android:viewportHeight="48"android:viewportWidth="150"><!-- 绘制底部的直线--><pathandroid:name="bottom"android:pathData="M 0,23L 140,23"android:strokeAlpha="0.8"android:strokeColor="@color/colorAccent"android:strokeLineCap="square"android:strokeWidth="1"/><!--对钩的处理大写的L:后面的数据就是直线的终点小写的l:后面的数据是增量--><pathandroid:name="right"android:pathData="M 128,13l 3,3l 5,-6"android:strokeWidth="2"android:strokeColor="@color/colorAccent"android:strokeLineCap="round"/></vector>

接着就是控制对勾和直线的动画效果,第一种动画:直线显示出来,对勾隐藏:

<animated-vector xmlns:android="http://schemas.android.com/apk/res/android"android:drawable="@drawable/et_bg"><targetandroid:name="bottom"android:animation="@animator/bottom_line_out" /><targetandroid:name="right"android:animation="@animator/right_default_gone" />
</animated-vector>

bottom_line_out动画代码:

<?xml version="1.0" encoding="utf-8"?>
<objectAnimator xmlns:android="http://schemas.android.com/apk/res/android"android:duration="300"android:propertyName="trimPathEnd"android:valueFrom="0"android:valueTo="1"android:valueType="floatType">
</objectAnimator>

right_default_gone动画代码:

<?xml version="1.0" encoding="utf-8"?>
<objectAnimator xmlns:android="http://schemas.android.com/apk/res/android"android:duration="1"android:valueFrom="1"android:valueTo="1"android:propertyName="trimPathStart"android:valueType="floatType">
</objectAnimator>

第二种动画就是直线和对勾隐藏,第三种动画就是对勾显示,与第一种动画都是类似就不在此贴代码了。

总结

通过本篇文章可以对SVG有一个比较基础的了解,以及如何在 Android下实现通过 SVG 实现我们的自定义动画效果!

Thanks!

Android自定义动画三-SVG动画相关推荐

  1. Android自定义view之围棋动画

    Android自定义view之围棋动画 好久不见,最近公众号内粉丝要求上新一篇有点难度的自定义view文章,所以它来了!! 干货文,建议收藏 文章目录 Android自定义view之围棋动画 前言 完 ...

  2. android view 渐变动画,Android自定义view渐变圆形动画

    本文实例为大家分享了Android自定义view渐变圆形动画的具体代码,供大家参考,具体内容如下 直接上效果图 自定义属性 attrs.xml文件 创建一个类 ProgressRing继承自 view ...

  3. android svg动画框架,Android实现炫酷SVG动画效果

    svg是目前十分流行的图像文件格式了,svg严格来说应该是一种开放标准的矢量图形语言,使用svg格式我们可以直接用代码来描绘图像,可以用任何文字处理工具打开svg图像,通过改变部分代码来使图像具有交互 ...

  4. android 海浪动画,android自定义波浪加载动画的实现代码

    本文实例为大家分享了android自定义波浪加载动画的具体代码,供大家参考,具体内容如下 效果图 1.自定义控件 WaveView package com.example.wh.myapplicati ...

  5. android 自定义加载动画效果,Android自定义View实现loading动画加载效果

    项目开发中对Loading的处理是比较常见的,安卓系统提供的不太美观,引入第三发又太麻烦,这时候自己定义View来实现这个效果,并且进行封装抽取给项目提供统一的loading样式是最好的解决方式了. ...

  6. Android自定义下拉刷新动画--仿百度外卖下拉刷新

    好久没写博客了,小编之前一段时间一直在找工作,从天津来到了我们的大帝都,感觉还不错.好了废话不多说了,开始我们今天的主题吧.现如今的APP各式各样,同样也带来了各种需求,一个下拉刷新都能玩出花样了,前 ...

  7. 属性动画Android动画,Android动画(三)属性动画Animator与Interpolator

    概述 继上一篇,Android中的视图动画和帧动画可以实现大部分的Android中的动画需求,但是有一个缺点,就是其事件响应区域并没有发生变化,这时候出现了属性动画完全弥补了这个缺点 属性动画结构 可 ...

  8. svg android动画制作,SVG动画案例的学习_SVG, SVG Animation, Animation, Web动画 教程_W3cplus...

    平面设计已成为2016年可见的趋势,显然,这就是SVG用法又重新走入人们的视野的原因.好处有很多: 独立的分辨率.跨浏览器兼容性以及DOM节点的可访问性.本文中,我们将看看如何使用SVG从简单的插图创 ...

  9. android 自定义图片加载动画效果,Android自定义加载动画-感染体

    Android自定义动画系列七,今天来分享第七个自定义Loading动画(InfectionBallBuilder),看上去感觉有种病毒源被感染的感觉,所以名字就叫感染体,这个动画做出来的效果,我不怎 ...

最新文章

  1. mysql编程的二维数组_调出mysql中数据,输出一个二维数组的表格
  2. ubuntu安装搜狗输入法的相关问题
  3. 取得成本中心组、成本要素组层级的几个BAPI
  4. Fragment的布局中自定义Layout的onSizeChanged添加组件失败的问题
  5. Rsync(远程同步):Linux中Rsync命令的10个实际示例
  6. pandas 设置多重索引_pandas dataframe多重索引常用操作
  7. 机器学习XGBoost 算法概述
  8. 【系统】VMware虚拟机安装黑苹果系统macOS 12.5详细步骤
  9. FlexSim软件PF模块标识详细解释
  10. SI4438可变长包数据收发
  11. vm虚拟机出现目标主机不支持CPUID的情况
  12. 利用cmd(命令提示符)taskkill结束进程的方法(命令结束进程)
  13. 生成登录验证码,点击更换验证码图片
  14. Linux系列: 777 755区别
  15. 偶尔娱乐一下应该无妨?
  16. APICloud(二):选择一张或多张图片
  17. 【并查集】HAOI破译密文
  18. ckeditor php 上传图片_ckeditor 4上传图片功能配置方法
  19. 计算机组装大赛策划书新闻稿,关于装机大赛策划书
  20. Linux系统下10款文件和磁盘加密工具

热门文章

  1. UVC摄像头驱动程序框架
  2. 数据标注员:时代的一粒沙,落到每个人身上都是一座山丨曼孚科技
  3. 商务统计_7 用图表演示数据 - 定量数据
  4. Gd-DOTA-NH2钆-四氮杂环配体-氨基PEG分子量可以选择1000、2000、3400和5000等等
  5. 卡特兰数(Catalan)的原理和题目
  6. devstack mysql_DevStack部署Openstack环境
  7. crx插件怎么将其添加到浏览器扩展中
  8. R型变压器220v和110v电压有什么不同的用途?
  9. 看曾国藩家书有感(1)
  10. 从零开始 之 使用 MapReduce 对文件进行词频统计