矢量圖形(VectorDrawable)使用幾何形狀的方式來描述圖像元素。矢量圖形非常適合于與設(shè)備無關(guān)的簡單或者合成的制圖或者不需要實(shí)現(xiàn)真實(shí)感的場合。矢量圖形的渲染是在運(yùn)行時(shí)開始的,因此它可以自適應(yīng)不同的屏幕,放大不會失真。
Android系統(tǒng)從5.0開始支持矢量圖,為開發(fā)者提供了添加復(fù)雜矢量圖形的強(qiáng)大功能,同時(shí)也提供了動畫顯示這些圖形的方法。
VectorDrawable
在Android項(xiàng)目中,創(chuàng)建一個(gè)矢量圖形,只需要在res/drawable新建xml文件,在<vector>元素下定義VectorDrawable的形狀。下面的例子定義了一個(gè)心形的vector drawable:
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="256dp"
android:height="256dp"
android:viewportHeight="32"
android:viewportWidth="32">
<group
android:name="group_love"
android:pivotX="15.0"
android:pivotY="15.0">
<path
android:fillColor="@color/pink_500"
android:pathData="M20.5,9.5
c-1.955,0,-3.83,1.268,-4.5,3
c-0.67,-1.732,-2.547,-3,-4.5,-3
C8.957,9.5,7,11.432,7,14
c0,3.53,3.793,6.257,9,11.5
c5.207,-5.242,9,-7.97,9,-11.5
C25,11.432,23.043,9.5,20.5,9.5z" />
</group>
</vector>

VectorDrawable通過<path>標(biāo)簽來定義一條路徑,<group>標(biāo)簽可以用來給path分組,為我們對路徑的組合操作提供方便。
pathData
pathData定義了vector drawable的路徑,它的值是繪制一個(gè)圖形所需要的信息。
可用于定義路徑(Path)的命令有:
- M = move to (移動到,從某點(diǎn)開始)
- L = line to (從上一點(diǎn)畫直線到)
- H = horizontal line to (水平畫直線到)
- V = vertical line to (垂直畫直線到)
- C = curve to (畫曲線到)
- S = smooth curve to (畫平滑曲線到)
- Q = quadratic Belzier curve (二次方程曲線)
- T = smooth quadratic Belzier curve (平滑二次方程曲線)
- A = elliptical Arc (畫橢圓)
- Z = close path (關(guān)閉路徑,直線連接終點(diǎn)與起點(diǎn))
注釋: 以上所有命令均允許小寫字母。大寫表示絕對定位,小寫表示相對定位。
了解pathData有一定的必要,但讓我們自己去想辦法使用pathData去繪制復(fù)雜的圖形有一定的困難,推薦兩個(gè)有用的工具:
- 矢量圖形制作工具:Adobe Illustrator; Inkscape
- 8000個(gè)已分類好的扁平化圖標(biāo)
VectorDrawable的pathData解析規(guī)則與svg相似,我們只需要生成或下載需要的圖形的svg文件,復(fù)制里面的path即可得到想要的VectorDrawable。
AnimatedVectorDrawable
AnimatedVectorDrawable是用來實(shí)現(xiàn)有動畫效果的VectorDrawable的,它可以讓<vector>里的<group>和<path>元素的屬性動態(tài)變化。基本的動畫效果有平移、旋轉(zhuǎn)、放大縮小、以及路徑繪制、形狀變換。
創(chuàng)建一個(gè)AnimatedVectorDrawable,需要:
存在一個(gè)要實(shí)現(xiàn)動畫效果的VectorDrawable
存在一個(gè)或多個(gè)屬性動畫文件
然后在res/drawable新建xml文件,在<animated-vector>元素下定義VectorDrawable的動畫。
下面的例子定義了心形vector drawable的動畫:
//anim_love_bounce.xml
<set xmlns:android="http://schemas.android.com/apk/res/android">
<objectAnimator
android:duration="1000"
android:propertyName="scaleX"
android:valueFrom="0.6"
android:valueTo="1"
android:valueType="floatType"
android:repeatMode="reverse"
android:repeatCount="infinite"
android:interpolator="@android:interpolator/bounce"/>
<objectAnimator
android:duration="1000"
android:propertyName="scaleY"
android:valueFrom="0.6"
android:valueTo="1"
android:valueType="floatType"
android:repeatMode="reverse"
android:repeatCount="infinite"
android:interpolator="@android:interpolator/bounce" />
</set>
//avd_love.xml
<?xml version="1.0" encoding="utf-8"?>
<animated-vector xmlns:android="http://schemas.android.com/apk/res/android"
android:drawable="@drawable/vd_love">
<target
android:animation="@animator/anim_love_bounce"
android:name="group_love" />
</animated-vector>
注意: <path>是沒有平移(translateX,translateY)、旋轉(zhuǎn)(rotation)、放大縮小(scaleX,scaleY)屬性的,因此無法使用屬性動畫來控制<path>實(shí)現(xiàn)平移、旋轉(zhuǎn)、放大縮小動畫;當(dāng)我們需要實(shí)現(xiàn)這些動畫時(shí),需要先將相關(guān)的<path>元素包裹在一個(gè)個(gè)的<group>元素中。
路徑繪制動畫
<objectAnimator xmlns:android="http://schemas.android.com/apk/res/android"
android:duration="800"
android:interpolator="@android:interpolator/linear_out_slow_in"
android:propertyName="trimPathStart"
android:valueFrom="0"
android:valueTo="1"
android:valueType="floatType" />
形狀變換動畫
<objectAnimator xmlns:android="http://schemas.android.com/apk/res/android"
android:duration="3000"
android:propertyName="pathData"
android:valueFrom="M300,70 l 0,-70 70,70 0,0 -70,70z"
android:valueTo="M300,70 l 0,-70 70,0 0,140 -70,0 z"
android:valueType="pathType" />