VectorDrawable – 第四章

前几篇文章中,我们知道了如何创建_VectorDrawable_以及制作path group的动画,也知道了如何渲染出路径的绘制效果。但是还有更多的动画方式,那就是修改SVG的path数据本身。这篇文章将讲解是如何做到的。

为了修改SVG的path数据,我们需要先了解一点SVG path的格式。这里不会详细的讲解,因为文档可以在这里找到:here。让我看看如何绘制一个简单的正方形:

res/drawable/square.xml

<?xml version="1.0" encoding="utf-8"?>
<vector xmlns:android="http://schemas.android.com/apk/res/android"
    android:viewportWidth="500"
    android:viewportHeight="500"
    android:width="500px"
    android:height="500px">
    <path android:name="square"
        android:fillColor="@color/sa_green"
        android:pathData="M100,100 L400,100 L400,400 L100,400 z" />
</vector>

 大部分代码看起来都很熟悉,不过我们还是来分析下path元素下面的pathData属性。首先记住viewport是500 x 500(像素单位),因此我们的工作将在这个区域中进行。pathData有5个参数(为了便于阅读,我在不同的参数之间用空格分割,但是空格并不是必须的,注意逗号不是参数分割符)。第一个参数值是M100,100,表示将当前的绘制点移动到100, 100的位置(大写字母M表示我们使用的是绝对坐标,我们可以使用小写字母m来表示相对坐标,这个规则适用于所有参数)。这将当前的位置定位到了正方形绘制区域的左上角。

接下来的三个参数:L400,100 L400,400 L100,400将会绘制一条依次从左上角-右上角-右下角-左下角的线条。同样我们依然使用绝对坐标。

最后一个参数z是将这条线条闭合。总的来说就是,当前的位置是在左下角,闭合意味着从当前位置绘制一条连接起始点的直线。

而填充色绿色,在Android Studio的预览中看起来如下:

square_drawable

 SVG path可以做更多的东西,但是这里一个简单的方形就满足我们的要求了。

下面我们需要像前面几篇文章中那样定义一个简单的AnimatedVectorDrawable来将属性动画(Animator)赋予这个path元素:

res/drawable/animated_square.xml

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

 现在到了关键部分-Animator自身。我们要实现将正方形向三角形动画过度。实现的方法是将开始值和结束值定义成两个不同的path。起始path是正方形(上面已经定义),结束path是三角形。

必须记住起始和结束path的参数个数要相等,同时这些参数的类型要匹配。我们的正方形path是由move命令(M开头表示move)开始,然后是3个line命令,和最后的关闭命令组成的,因此三角形也必须符合这个模式。但是三角形只需要三条线,而正方形是四条线,因此我们需要一点技巧。我们将正方形上边的中点作为顶点,并且在这个点绘制两次。

然后设置android:valueType="pathType",属性动画将按照一定的插值播放动画:

res/animator/to_triangle.xml

<?xml version="1.0" encoding="utf-8"?>
<objectAnimator xmlns:android="http://schemas.android.com/apk/res/android"
    android:duration="1000"
    android:interpolator="@android:interpolator/decelerate_cubic"
    android:repeatMode="reverse"
    android:repeatCount="1"
    android:propertyName="pathData"
    android:valueType="pathType"
    android:valueFrom="M100,100L400,100L400,400L100,400z"
    android:valueTo="M250,100L250,100L400,400L100,400z" />

别慌,为啥不顺带改变下颜色呢?也很简单,给_AnimatedVectorDrawable_再增加一个target就是了:

res/drawable/animated_square.xml

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

接下来创建一个_ObjectAnimator_将颜色从绿色变为黄色:

res/animator/colour.xml

?xml version="1.0" encoding="utf-8"?>
<objectAnimator xmlns:android="http://schemas.android.com/apk/res/android"
    android:duration="1000"
    android:propertyName="fillColor"
    android:valueType="intType"
    android:repeatCount="1"
    android:repeatMode="reverse"
    android:interpolator="@android:interpolator/decelerate_cubic"
    android:valueFrom="@color/sa_green"
    android:valueTo="@color/vivid_yellow" />

 完美的实现了将绿色正方形动画过度到黄色三角形的动画:

 66555555.gif

值得再次提出的是,除了调用动画的代码外,我们没有使用任何java代码。

到此关于VectorDrawable的总结就完了,我们祈祷VectorDrawable的兼容包尽快出现。

这篇文章的代码在这里可以获得: here

英文原文: VectorDrawables – Part 4