??Google在Android 5.x中增加了對svg矢量圖形的支持,這對于創(chuàng)建新的高效率動畫具有非常重大的意義。首先,我們來看看什么是svg。
1.什么是svg圖形
A.可伸縮矢量圖形(Scalable Vector Graphics)
B.定義用于網(wǎng)絡(luò)的基于矢量的圖形
C.使用XML格式定義圖形
D.圖像在放大或改變尺寸的情況下其圖形質(zhì)量不會有所損失
E.萬維網(wǎng)聯(lián)盟的標(biāo)準(zhǔn)
F.與諸如DOM和XML之類的W3C標(biāo)準(zhǔn)是一個整體
??在Android 5.x之前,我們使用svg必須通過第三方的庫來實現(xiàn);而在Android 5.x之后,Android中添加了對<path>標(biāo)簽的支持,從而能夠使開發(fā)者使用svg來創(chuàng)建更加豐富的動畫效果。
2.svg與Bitmap的區(qū)別
??Bitmap(位圖)是通過在每個像素點上存儲色彩信息來表達圖像,而svg是一個繪圖標(biāo)準(zhǔn)。與Bitmap相比,svg最大的優(yōu)點就是放大不會失真。而且Bitmap需要為不同分辨率設(shè)計多套圖標(biāo),而矢量圖則不需要。
3.<path>標(biāo)簽
??使用<path>標(biāo)簽來創(chuàng)建svg,就像用指令的方式來控制一只畫筆,例如移動畫筆到某一坐標(biāo)位置,畫一條直線,畫一條曲線,結(jié)束。<pah>標(biāo)簽所支持的指令有以下幾種:
A. M = moveto(x, y):將畫筆移動到指定的坐標(biāo)位置上,但是并沒有發(fā)生繪制。
B. L = lineto(x, y):畫一條直線到指定的坐標(biāo)位置上。
C. H = horizontal lineto(x):畫水平線在指定的x坐標(biāo)位置。
D. V = vertical lineto(y):畫一條垂直線在指定的y坐標(biāo)位置。
E. C = curveto(x1, y1, x2, y2, endX, endY):三次貝賽曲線
F. S = smooth curveto(x2, y2, endX, endY):三次貝賽曲線
G. G = quadratic Belzier curveto(x, y, endX, endY):二次貝賽曲線
H. T = smooth quadratic Belizer curveto(endX, endY):映射前面路徑后的終點
I. A = elliptical Arc(rx, ry, xRotation, flag1, flag2, x, y):弧線
J. Z = colsepath():關(guān)閉路徑
??在使用上面的指令的時候,我們還需要注意幾點:
A. 坐標(biāo)軸是以(0,0)為中心的, x軸水平向右,y軸水平向下。
B. 所有指令大小寫均可。大寫表示絕對坐標(biāo),參照全局坐標(biāo)系;小寫表示相對坐標(biāo),參照父容器的坐標(biāo)系。
C. 指令和數(shù)據(jù)間的空格可以省略。
D. 同一個指令可以使用多次。
4.svg常用指令
(1).L指令
繪制直線的指令時“L”,代表從當(dāng)前點繪制直線到指定點?!癓”之后的參數(shù)是一個點坐標(biāo),例如:“L 200 400”繪制直線。同時還可以使用“H”和“V”指令來繪制水平、豎直線,后面的參數(shù)是X坐標(biāo)(H指令) 或者y坐標(biāo)(V指令)。
(2).M指令
M指令類似于Android繪圖中Path類中的moveto方法,即代表將畫筆移動到某一點,但并不發(fā)生繪制的動作
(3).A指令
A指令是用來繪制一段弧線的,且允許弧線不閉合??梢园袮指令繪制的弧線想象成是橢圓的某一段,A指令一下有七個參數(shù):
??A. rx, ry 表示的是橢圓的半軸大小
??B.xRotation 指橢圓的X軸與水平方向順時針方向的夾角,可以想象成一個水平的橢圓繞中心點順時針旋轉(zhuǎn)xRotation的角度。
??C.flag1 只有兩個值,1表示繪制大弧度弧線,0表示繪制小弧度弧線
??D.flag2 只有兩個值,確定從起點到終點的方向,1為順時針,0為逆時針。
5.Android中使用svg
??Google在Android 5.x中提供了下面兩個新的API來幫助支持svg:
????(1).VectorDrawable
????(2).AnimatedVectorDrawable
??其中,VectorDrawable讓你可以創(chuàng)建基于XML的svg圖形,并且結(jié)合AnimatedVectorDrawable來實現(xiàn)動畫效果。
6.VectorDrawable的相關(guān)屬性和作用
??在Android中,我們可以使用XMl文件來創(chuàng)建SVG圖形,在XML文件中,必須將其根元素設(shè)置為<vector>才行。
??下面介紹一下在XML文件中的相關(guān)屬性的作用
??<vector>:定義一個vector類型的可繪制的對象。
| 屬性名 | 解釋 |
|---|---|
| Android:name | 定義該對象的名字 |
| Android:width | 定義該對象的寬,該屬性支持所有的像素單位,通常使用dp |
| Android:height | 定義該對象的高,同上 |
| Android:viewportWidth | 視口的寬,視口通常是設(shè)備上用于繪制圖形的畫布 |
| Android:tint | 該對象的著色色彩,默認是沒有色彩的 |
| Android:tintMode | 該對象的著色模式,默認為src_in |
| android:autoMirrored | 當(dāng)該對象的布局是RTL(right-to-left),是否需要一個鏡像。默認是false |
| android:alpha | 該對象的透明度。默認為1,表示不透明 |
??<group>:定義一個路徑的組或者是一個子組,包含圖形的轉(zhuǎn)換信息。這些轉(zhuǎn)換信息定義在與視口相同的坐標(biāo)系中,同時轉(zhuǎn)換信息支持縮放、旋轉(zhuǎn)以及移動。
| 屬性名 | 解釋 |
|---|---|
| Android:name | 定義group的名字 |
| Android:rotation | 定義group的旋轉(zhuǎn)角度。默認為0 |
| Android:pivotX | 定義group旋轉(zhuǎn)和縮放的中心點X坐標(biāo),該坐標(biāo)在視口(viewport)的坐標(biāo)系中。默認為0 |
| Android:pivotY | 同上 |
| Android:scaleX | X坐標(biāo)上的縮放度。默認為1 |
| Android:scaleY | 同上 |
| Android:translateX | X坐標(biāo)上的移動,該坐標(biāo)在視口的坐標(biāo)系中。默認為0 |
| Android:translateY | 同上 |
??<path>:定義繪制的路徑
| 屬性名 | 解釋 |
|---|---|
| Android:name | 定義路徑的名字 |
| Android:pathData | 使用svg屬性來繪制路徑。路徑定在視口(viewport)里面 |
| Android:fillColor | 定義填充路徑的顏色??梢允穷伾?,或者在API 23+中,顏色狀態(tài)列表或者漸變顏色 |
| Android:strokeColor | 定義填充路徑輪廓的顏色。其余的同上 |
| Android:strokeWidth | 定義路徑線條的寬度。默認為0 |
| Android:strokeAlpha | 定義路徑線條的透明度。默認為1 |
| Android:fillAlpha | 定義填充路徑的透明度。默認為1 |
| Android:trimPathStart | 從路徑開始的地方,截取路徑一部分,范圍是0到1。默認為0 |
| Android:trimPathEnd | 從路徑結(jié)束的地方,截取路徑的一部分,范圍是0到1。默認為1 |
| Android:trimPathOffset | 移動修剪的區(qū)域(顯示區(qū)域包括開始和結(jié)束),范圍是0到1。默認為0 |
| Android:strokeLineCap | 定義線的兩端的樣式,有 butt, round, square三種模式。默認為butt |
| Android:strokeLineJin | 定義線段連接處的樣式,有miter,round,bevel三種模式。默認為miter |
| Android:strokeMiterLimit | 設(shè)置斜角的上限。默認為4 |
| Android:fillType | 定義填充模式,有evenOdd、nonZero兩種模式。默認為nonZero |
??<clip-path>:給一個繪制的路徑定義一個特定的截取路線,也就是說在已經(jīng)存在的路線上定義它的截取路線,不繪制截取的部分。注意:截取路徑只能定義在特定的group中或者是group的子組中。
| 屬性名 | 解釋 |
|---|---|
| Android:name | 定義截取路徑的名字 |
| Android:pathData | 同path中的pathData |
7.在Android使用相關(guān)的屬性來繪制圖形
??Android中使用svg繪制的圖形也是Drawable對象,不過是VectorDrawable對象。因此,我們可以在Drawable文件夾中定義相關(guān)的XML文件來繪制我們的圖形,跟平常的Drawable對象繪制方式是一樣的,只是相關(guān)的屬性是不同的。
<?xml version="1.0" encoding="utf-8"?>
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:height="200dp"
android:width="200dp"
android:viewportWidth="110"
android:viewportHeight="110"
>
<group
android:name="test"
android:pivotX="55"
android:pivotY="55"
>
<path android:strokeColor="@android:color/holo_blue_bright"
android:strokeWidth="2"
android:pathData="M 26,50
a 25,25, 0,0,0,25,25"
/>
</group>
</vector>
??如上面的例子,我們就繪制了一條弧線。
??經(jīng)過上面的定義,就繪制了一個svg圖形。關(guān)于它的引用,就像使用平常的Drawable一樣。
<ImageView
android:id="@+id/id_imageView"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:src="@drawable/demo"
/>
8.給svg圖形增加動畫
??通過上面的步驟,我們定義了一個svg圖形,將其設(shè)置給一個ImageView。但是有沒有發(fā)現(xiàn),這并沒有什么特點???好像跟我們平常使用的Drawable是一樣的。其實并不是這樣的,我們還可以將一個動態(tài)的svg圖形設(shè)置給一個控件,也就是要說的,給一個svg圖形增加動畫,也就是之前說的AnimatedVectorDrawable。
??AnimatedVectorDrawable的作用就是給一個VectorDrawable增加動畫效果。Google將AnimatedVectorDrawable比喻成膠水,通過AnimatedVectorDrawable來連接靜態(tài)的VectorDrawable和動態(tài)的ObjectDrawable。

(1). 靜態(tài)的VectorDrawable:
<?xml version="1.0" encoding="utf-8"?>
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:height="200dp"
android:width="200dp"
android:viewportWidth="110"
android:viewportHeight="110"
>
<group
android:name="test"
android:pivotX="55"
android:pivotY="55"
>
<path android:strokeColor="@android:color/holo_blue_bright"
android:strokeWidth="2"
android:pathData="M 26,50
a 25,25, 0,0,0,25,25"
/>
</group>
</vector>
(2). 動態(tài)的ObjectorAnimator:
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android">
<objectAnimator
android:duration="500"
android:propertyName="rotation"
android:valueFrom="0"
android:valueTo="360"
android:repeatCount="100"
android:startOffset="-1"
android:interpolator="@android:anim/overshoot_interpolator"
/>
</set>
(3). 粘合起來的AnimatedVectorDrawable:
<?xml version="1.0" encoding="utf-8"?>
<animated-vector xmlns:android="http://schemas.android.com/apk/res/android"
android:drawable="@drawable/demo"
>
<target
android:animation="@animator/anim"
android:name="test"/>
</animated-vector>
??需要的注意的是:AnimatedVectorDrawable中指定的target的name屬性的內(nèi)容必須與VectorDrawable中需要作用的name屬性必須保持一致,這樣系統(tǒng)才能找到要實現(xiàn)動畫效果的元素。最后,通過AnimatedVectorDrawable中target的animation屬性,將一個動畫作用到對應(yīng)name的元素上。
??在<group>標(biāo)簽和<path>標(biāo)簽中,添加了rotation、fillColor、pathData等屬性,那么在ObjectAnimator中,就可以通過指定Android:propertyName="XXXX"屬性來選擇控制哪一種屬性,通過Android:valueFrom="XXXX"和Android:valueTo="XXXX"屬性,可以控制動畫的起始值。唯一需要注意的是:如果指定控制的屬性為pathData,那么需要添加一個屬性--Android:valueType="pathType"來告訴系統(tǒng)進行pathData變換。
??在控件引用Drawable的時候,記住引用的是AnimatedVectorDrawable,而不是VectorDrawable。
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:gravity="center"
android:orientation="vertical">
<ImageView
android:id="@+id/id_imageView"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:src="@drawable/demo1"
/>
</LinearLayout>
??當(dāng)我們引用一個動態(tài)的AnimatedVectorDrawable后,就可以在Java代碼中使用動畫效果了。
mImageView = (ImageView) findViewById(R.id.id_imageView);
((Animatable)mImageView.getDrawable()).start();