這篇文章是對VectorDrawable的簡單介紹,主要參考了android官方文檔。更詳細的講解請參考stylingandroid網站的3篇文章 https://blog.stylingandroid.com/vectordrawables-part-1/ ,或者關注本站將發表的翻譯版本。
一、VectorDrawable
在android5.0(API Level 21)中,我們可以使用矢量圖:vector drawable,vector drawable的特點是它不會因爲圖像的縮放而失真。在安卓開發中也就意味着你不需要爲不同分辨率的設備定義不同大小的圖片資源,只需一個vector drawable就夠了。在安卓中與vector drawable資源對應的類是VectorDrawable。要創建一個vector drawable,你需要在xml的<vector>的元素下定義好vector drawable的形狀數據。
下面的例子定義了一個心形的vector drawable:
- <!-- res/drawable/heart.xml -->
- <vector xmlns:android="http://schemas.android.com/apk/res/android"
- <!-- intrinsic size of the drawable -->
- android:height="256dp"
- android:width="256dp"
- <!-- size of the virtual canvas -->
- android:viewportWidth="32"
- android:viewportHeight="32">
- <!-- draw a path -->
- <path android:fillColor="#8fff"
- 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" />
- </vector>
其中這裏最讓人不解的是pathData
裏面的那些數字,正是這些數字讓這個drawable呈現出心形。pathData
指的是繪製一個圖形所需要的路徑信息,那麼問題來了,我怎麼知道該如何繪製呢?
w3c的文檔中詳細講解了繪製的規則:http://www.w3.org/TR/SVG11/paths.html#PathData 。其實在svg格式的圖像中也是使用這種規則,而且在安卓中android.graphics.Path
api對路徑的定義也差不多是這種規則。
雖然有對path 規則的繪製教程,但是要創造出現有安卓中各種圖標的效果是很難的,要讓VectorDrawable有實際價值,肯定不能讓開發者去想辦法實現這些圖形的繪製,而是原本就有很多現成的圖像可用,8000個已分類好的扁平化圖標(PNG/SVG/WEBFONT) 從網上的搜索結果來看svg的圖標是大有人在。
二、AnimatedVectorDrawable
AnimatedVectorDrawable可以讓VectorDrawable動起來。
AnimatedVectorDrawable通過改變VectorDrawable的屬性來讓VectorDrawable呈現動畫效果,其實現實際上是試用了屬性動畫。
通常定義一個AnimatedVectorDrawable需要以下三個xml文件:
1.vector drawable本身:res/drawable/中定義一個有<vector>元素的xml文件,參考上面對VectorDrawable的定義。
2.vector drawable的動畫文件(Animated vector drawable):res/drawable/中定義一個有<animated-vector>元素的xml文件。
3.一個或者多個屬性動畫文件:res/drawable/中定義一個有<objectAnimator>元素的xml文件。
Animated vector drawable可以讓<group>和<path>元素的屬性動態變化。<group>定義一組path或者子group,而<path>元素定義需要繪製的路徑。當你想讓VectorDrawable呈現動畫效果,在定義VectorDrawable的時候需要爲group和path的android:name屬性設置一個唯一的名字,以便在Animated vector drawable中找到它們。比如
- <!-- res/drawable/vectordrawable.xml -->
- <vector xmlns:android="http://schemas.android.com/apk/res/android"
- android:height="64dp"
- android:width="64dp"
- android:viewportHeight="600"
- android:viewportWidth="600">
- <group
- android:name="rotationGroup"
- android:pivotX="300.0"
- android:pivotY="300.0"
- android:rotation="45.0" >
- <path
- android:name="v"
- android:fillColor="#000000"
- android:pathData="M300,70 l 0,-70 70,70 0,0 -70,70z" />
- </group>
- </vector>
其中group的android:name爲rotationGroup而path的android:name爲v。
在Animated vector drawable中就分別通過rotationGroup和v找到vector drawable的group和path:
- <!-- res/drawable/animvectordrawable.xml -->
- <animated-vector xmlns:android="http://schemas.android.com/apk/res/android"
- android:drawable="@drawable/vectordrawable" >
- <target
- android:name="rotationGroup"
- android:animation="@anim/rotation" />
- <target
- android:name="v"
- android:animation="@anim/path_morph" />
- </animated-vector>
其中animation代表一個ObjectAnimator或者AnimatorSet ,在本例中,第一個animator將目標group旋轉360度:
- <!-- res/anim/rotation.xml -->
- <objectAnimator
- android:duration="6000"
- android:propertyName="rotation"
- android:valueFrom="0"
- android:valueTo="360" />
第二個animator是將vector drawable的path元素從一個形狀轉變到另一個形狀。但是這兩個形狀必須滿足一定的條件:必須要有一致的命令(command)個數(逗號分割開的爲命令),並且每個命令的參數個數也必須一致。
- <!-- res/anim/path_morph.xml -->
- <set xmlns:android="http://schemas.android.com/apk/res/android">
- <objectAnimator
- 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" />
- </set>
轉自:http://www.jcodecraeer.com/a/anzhuokaifa/androidkaifa/2015/0123/2346.html