Android---动画机制(四)----SVG

本文详细介绍了如何使用SVG在Android中创建高效动画。包括基本的path标签使用方法,如何创建和使用VectorDrawable及AnimatedVectorDrawable,以及具体的动画案例。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

Google在android5.X中增加了对SVG矢量图形的支持,对高效率的动画具有非常重大的意义.

path标签

使用<path>标签创建SVG,就像用指令的方式来控制一直画笔类似.使用方法有以下几种:

  • 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 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):弧线
  • Z=closepath();关闭路径

使用注意事项:

  1. 所有指令大小写均可,大写绝对定位,参照全局坐标系,小写相对定位,参照父容器坐标系.
  2. 指令和数据间的空格可以省略
  3. 同一指令出现多次可以只用一个
  4. 使用A命令来绘制一段弧线,且允许弧线不闭合,可以把A命令看做成椭圆的某一段
    (1)RX,RY指所在椭圆的半轴大小
    (2)XROTATION指椭圆的X轴与水平方向顺时针防线夹角,可以想象成一个水平的椭圆绕中心点顺时针旋转XROTATION度
    (3)FLAG1只有2个值,1表示大角度弧线,0为小角度弧线
    (4)FLAG2也是2个值,确定从起点至终点的方向,1为顺时针,0为逆时针.
    (5)X,Y轴为终点坐标

使用SVG–VectorDrable

VectorDrable
在XML文件中创建SVG图形首先通过<vector> 标签来声明对SVG的使用

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

heigth和width表示该SVG图形的具体大小 viewportWidth和viewportHeight表示SVG图形的划分比例.两种类型的设置的比例必须保持一直,不然图形就会发生压缩或者是形变.

<vector xmlns:android="http://schemas.android.com/apk/res/android"
    android:height="200dp"
    android:width="200dp"
    android:viewportWidth="100"
    android:viewportHeight="100">
    <group android:name="Group Name"
           android:rotation="0">
        <!--fillColor  表示绘制填充图形
            strokeColor 绘制非填充图形
            -->
        <path android:strokeColor="@color/colorPrimaryDark"
            android:strokeWidth="3"
            android:pathData="
            M 25 50
            a 25,25 0 1,0 50,0"/>
    </group>
</vector>

这里写图片描述

AnimatedVectorDrawable

AnimatedVectorDrawable的作用是给VectorDrawable提供动画效果.
AnimatedVectorDrawable比喻一个胶水,来连接静态的VectorDrawable和动态的objectAnimator
首先应该在XML文件中定义:

<animated-vector xmlns:android="http://schemas.android.com/apk/res/android"
    android:drawable="@drawable/svg">
    <!--在这里object_animator 对应的是objectAniator属性动画
        name则必须与VectorDrawable中需要作用的name属性保持一致-->
    <target
        android:animation="@animator/object_animator"
        android:name="Group_name"/>

</animated-vector>

svg:

<vector xmlns:android="http://schemas.android.com/apk/res/android"
    android:height="200dp"
    android:width="200dp"
    android:viewportWidth="100"
    android:viewportHeight="100">
    <group android:name="Group_Name"
           android:rotation="0">
        <!--fillColor  表示绘制填充图形
            strokeColor 绘制非填充图形
            -->
        <path android:strokeColor="@color/colorPrimaryDark"
            android:strokeWidth="3"
            android:pathData="
            M 25 50
            a 25,25 0 1,0 50,0"/>
    </group>
</vector>

最后通过JAVA代码实现:

 AnimatedVectorDrawable drawable= (AnimatedVectorDrawable) imageView.getDrawable();
                drawable.start();

注意
<group> 标签和<path> 标签中添加了rotation fillColor pathData等属性,在objectAnimator中可以通过指定的android:propertyName="XXXX" 来选择控制哪一种属性. android:valueFrom和android:valueTo 控制其实值和终止值
如果指定的属性为pathData那么就要添加一个属性android:valueType="pathType"来告诉系统进行pathData变换

实例

线性动画

<objectAnimator
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:duration="5000"
    android:propertyName="pathData"
    android:valueFrom="
    M 20,80
    L 50,80,80,80"
    android:valueTo="
    M 20,80
    L 50,50,80,80"
    android:valueType="pathType"
    android:interpolator="@android:anim/accelerate_decelerate_interpolator"
 >

</objectAnimator>
<vector xmlns:android="http://schemas.android.com/apk/res/android">
    android:height="200dp"
    android:width="200dp"
    android:viewportWidth="100"
    android:viewportHeight="100">
    <group >
        <!--path1和path2分别绘制了两条直线,每条直线又三个点控制
            即起始点和终点,形成初始状态-->
        <path
            android:name="path1"
            android:strokeColor="@android:color/background_dark"
            android:strokeWidth="5"
            android:strokeLineCap="round"
            android:pathData="
            M 20 80
            L 50,80,80,80"/>
        <path
            android:name="path2"
            android:strokeColor="@android:color/background_dark"
            android:strokeWidth="5"
            android:strokeLineCap="round"
            android:pathData="
            M 20,20
            L 50,20,80,20"/>
    </group>
</vector>

效果图:
这里写图片描述

模拟三球仪

首先绘制静态的日地月系统

<vector xmlns:android="http://schemas.android.com/apk/res/android"
    android:height="200dp"
    android:width="200dp"
    android:viewportHeight="100"
    android:viewportWidth="100">
    <!--pivot设置圆心-->
    <group
        android:name="sun"
        android:pivotX="60"
        android:pivotY="50"
        android:rotation="0">
        <path
            android:name="path_sun"
            android:fillColor="@android:color/holo_blue_light"
            android:pathData="
            M 50,50
            a 10,10 0 1,0 20,0
            a 10,10 0 1 0 -20,0"/>
        <group
            android:name="earth"
            android:pivotX="75"
            android:pivotY="50"
            android:rotation="0"
            >
            <path
                android:name="path_earth"
                android:fillColor="@android:color/holo_orange_dark"
                android:pathData="
                M 70,50
                a 5,5 0 1,0 10,0
                a 5,5 0 1,0 -10,0"
                />
            <group>
                <path
                    android:fillColor="@android:color/holo_red_dark"
                    android:pathData="
            M 90,50
            m -5,0
            a 4,4 0 1,0 8 0
            a 4,4 0 1,0 -8,0"/>
            </group>
        </group>
    </group>
</vector>

然后下面对两个group分别进行SVG动画.
sun动画:

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

</objectAnimator>

earth动画:

<objectAnimator xmlns:android="http://schemas.android.com/apk/res/android"
    android:duration="5000"
    android:propertyName="rotation"
    android:valueFrom="0"
    android:valueTo="1800">

</objectAnimator>

最后是粘合剂:

<animated-vector xmlns:android="http://schemas.android.com/apk/res/android" android:drawable="@drawable/earth_vector">
    <target
        android:animation="@anim/path_earth"
        android:name="earth"/>
    <target
        android:animation="@anim/path_sun"
        android:name="sun"/>
</animated-vector>

效果图如图所示:
这里写图片描述

轨迹动画

将propertyName指定为trimPathStart这个属性用来控制一个SVG Path的显示比例,例如一个圆形的SVG,使用trimPathStart动画,可以将画出一个圆一样来绘制一个圆,从而形成一个轨迹动画效果
下面实现一个搜索框中有一个放大镜,点击以后放大镜会按照绘制的轨迹逐渐消失:
首先绘制静态的矢量动画:

<vector xmlns:android="http://schemas.android.com/apk/res/android"
    android:width="160dp"
    android:height="30dp"
    android:viewportHeight="30"
    android:viewportWidth="160"
    >
    <!--放大镜-->
    <path
        android:name="search"
        android:pathData="
        M 141 17
        A 9,9 0 1,1 142,16
        L149,23"
        android:strokeAlpha="0.8"
        android:strokeLineCap="round"
        android:strokeColor="#ff2570be"
        android:strokeWidth="2"/>
    <!--横线-->
    <path
        android:name="bar"
        android:pathData="M0,23 L149,23"
        android:strokeAlpha="0.8"
        android:strokeColor="#ff2570be"
        android:strokeLineCap="square"
        android:strokeWidth="2"/>
</vector>

属性动画效果

<objectAnimator xmlns:android="http://schemas.android.com/apk/res/android"
    android:duration="1500"
    android:interpolator="@android:interpolator/accelerate_decelerate"
    android:propertyName="trimPathStart"
    android:valueFrom="0"
    android:valueTo="1"
    android:valueType="floatType">

</objectAnimator>

粘合剂:

<animated-vector xmlns:android="http://schemas.android.com/apk/res/android" android:drawable="@drawable/search_vector">
    <target
        android:animation="@anim/search_obj"
        android:name="search"/>
</animated-vector>

效果图
这里写图片描述

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值