SVG的全稱是Scalable Vector Graphics(可縮放矢量圖形),它不會因為圖像放大而失真,且占用內存小,同時搭配Path動畫,能夠實現一些意想不到的效果。
Android中的SVG圖像又叫Vector圖像,它是對原生的SVG進行了簡化,利用path來實現繪制。
1、VetcorDrawable
1.1、Vector圖形制作
我們可以在svg編輯網頁上制作好SVG圖像,然后通過Android Studio中的Vector Asset Studio,將SVG轉換成Vector。
轉換后代碼格式大致如下:
<?xml version="1.0" encoding="utf-8"?>
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="200dp"
android:height="100dp"
android:viewportWidth="100"
android:viewportHeight="50">
<path
android:name="bar"
android:pathData="M50,23 L100,25"
android:strokeWidth="2"
android:strokeColor="@android:color/darker_gray" />
</vector>
1.2、vector標簽屬性
標簽 | 含義 |
---|---|
width | 圖形的具體寬度 |
height | 圖形的具體高度 |
viewportWidth | 圖形橫向被劃分的個數 |
viewportHeight | 圖形縱向被劃分的個數 |
用于vector圖形是矢量圖,即無限放大也不會失真,所以要指定其寬高。
同時圖形中的坐標值,也不能依據寬高的具體值大小,只是就引入了劃分比例大小,即viewportXXX
。
舉例說明:本例中,將大小為200dp x 100dp
的圖像,劃分出100 x 50
個小份,每份尺寸為2dp x 2dp
;而android:pathData
屬性中的坐標值,就是相對于這100 x 50
個小份所決定的。如坐標(50,50),就對應本圖形底部中點。
1.3、path標簽屬性
1、常用屬性
path標簽具有以下幾個常用屬性。
標簽 | 含義 |
---|---|
name | 聲明一個標記,類似于ID,便于對其做動畫的時候順利地找到該節(jié)點 |
strokeWidth | 畫筆的寬度 |
fillColor | 填充顏色 |
fillAlpha | 填充顏色的透明度 |
strokeColor | 描邊顏色 |
strokeWidth | 描邊寬度 |
strokeAlpha | 描邊透明度 |
strokeLineJoin | 折線拐角形狀,取值有miter(結合處為銳角)、round(結合處為圓弧)、bevel(結合處為直線) |
strokeLineCap | 畫出線條的端點的形狀(線帽),取值有butt(無線帽)、round(圓形線帽)、square(方形線帽) |
strokeMiterLimit | 當兩條線段以銳角相交的時候,斜面可能很長,視覺上顯的不協(xié)調。 1、本屬性為斜面的長度設置了一個上限,當超出這個上限,它就變成斜角。只在strokeLineJoin為miter時有效。 2、實際上,它表示斜面長度和線條長度的比值,默認值是10,意味著一個斜面的長度不應該超過線條寬度的10 倍。 |
2、 android:trimPathStart
指定路徑的開始位置,取值為0~1。當取值為0時,表示從頭部開始;當取值為1時,整條路徑不可見。
3、 android:trimPathEnd
指定路徑的結束,取值為0~1。當取值為0時,整條路徑不可見,當取值為1,整條路徑顯示完整。當截取的路徑超出范圍時,會從開始位置繼續(xù)累計。
4、 android:trimPathOffset
指定結果路徑的偏移距離,取值為0~1。當取值為0時,不進行位移,當取值為1,位移整條路徑長度。
5、android:pathData
指定圖形內容,通過一系列指令和坐標,自動生成對應的圖像。
1.4、Vector的常用語法
即Vector中path標簽下android:pathData
屬性里字符串的語法。格式如下:
符號 | 使用 | 解釋 |
---|---|---|
M = moveto | M X,Y | 將畫筆移動到指定的坐標位置 |
L = lineto | L X,Y | 畫直線到指定的坐標位置 |
H = horizontal lineto | H V | 水平繪制直線到X坐標 |
V = vertical lineto | V Y | 垂直繪制直線到Y坐標 |
Q = quadratic Belzier curve | Q X,Y,ENDX,ENDY | 二次貝塞曲線 |
T = smooth quadratic Belzier curve | T ENDX,ENDY | 二次貝塞曲線 將上一指令的終點作為貝塞爾曲線的起點 |
C = curveto | C X1,Y1,X2,Y2,ENDX,ENDY | 三次貝塞曲線 |
S = smooth curveto | S X2,Y2,ENDX,ENDY | 三次貝塞曲線 將上一指令的終點作為貝塞爾曲線的起點 |
A = elliptical Arc | A RX,RY,XROTATION,FLAG1,FLAG2,X,Y | 弧線 |
Z = closepath | Z | 關閉路徑 |
其中A指令繪制一條弧線,各個參數含義如下:
參數 | 含義 |
---|---|
RX,RY | 橢圓的半軸大小 |
XROTATION | 橢圓的X軸和水平方向順時針方向的夾角 |
FLAG1 | 只有兩個值,1表示大角度弧度,0表示小角度弧度 |
FLAG2 | 只有兩個值,確定從起始點到終點的方向,1表示順時針,О表示逆時針 |
在使用上面的指令時,需要注意以下幾點。
1、坐標軸以(0,0)為中心,X軸水平向右,Y軸水平向下。
2、所有指令大小寫均可。大寫絕對定位,參照全局坐標系;小寫相對定位,參照父容器坐標系。
3、指令和數據間的空格可以省略。
4、同一指令出現多次可以只用一個。
1.5、group標簽
group標簽主要是將同一個Vector文件中,多個Path組成的圖像當做一個整體,便于動畫執(zhí)行。包含以下屬性:
標簽 | 含義 |
---|---|
name | 組的名字,用于與動畫相關聯(lián) |
rotation | 指定該組圖像的旋轉度數 |
pivotX | 定義縮放和旋轉該組時的X參考點,該值是相對于vector 的 viewport值來指定的 |
pivotY | 定義縮放和旋轉該組時的Y參考點,該值是相對于vector 的 viewport值來指定的 |
scaleX | 指定該組X軸縮放大小 |
scaleY | 指定該組Y軸縮放大小 |
translateX | 指定該組沿X軸平移的距離 |
translateY | 指定該組沿Y軸平移的距離 |
1.6、使用VetcorDrawable
gradle文件中配置:
android {
defaultConfig {
vectorDrawables.useSupportLibrary = true
}
}
ImageView or ImageButton
app:srcCompat="@drawable/vector_image"
Button
通過selector來進行設置,并開啟下面的設置
static{
AppCompatDelegate.setCompatVetcorFromResourcesEnabled(true);
}
2、AnimatedVectorDrawable
AnimatedVectorDrawable與VectorDrawable名字上多了一個Animated,這也是它們自己最大的區(qū)別,AnimatedVectorDrawable 擁有執(zhí)行動畫的能力。
2.1、AnimatedVectorDrawable使用
1、創(chuàng)建vector圖片
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportWidth="24.0"
android:viewportHeight="24.0">
<group android:name="left">
<path
android:fillColor="#8C9EFF"
android:pathData="M9.01,14L2,14v2h7.01v3L13,15l-3.99,-4v3z" />
</group>
<group android:name="right">
<path
android:fillColor="#8C9EFF"
android:pathData="M14.99,13v-3L22,10L22,8h-7.01L14.99,5L11,9l3.99,4z" />
</group>
</vector>
2、創(chuàng)建左右動畫
左箭頭動畫
<?xml version="1.0" encoding="utf-8"?>
<objectAnimator xmlns:android="http://schemas.android.com/apk/res/android"
android:duration="1000"
android:interpolator="@android:interpolator/anticipate_overshoot"
android:propertyName="translateX"
android:repeatCount="infinite"
android:repeatMode="reverse"
android:valueFrom="0"
android:valueTo="10"
android:valueType="floatType"/>
右箭頭動畫
<?xml version="1.0" encoding="utf-8"?>
<objectAnimator xmlns:android="http://schemas.android.com/apk/res/android"
android:duration="1000"
android:interpolator="@android:interpolator/anticipate_overshoot"
android:propertyName="translateX"
android:repeatCount="infinite"
android:repeatMode="reverse"
android:valueFrom="0"
android:valueTo="-10"
android:valueType="floatType"/>
3、配置動畫粘合劑
<?xml version="1.0" encoding="utf-8"?>
<animated-vector xmlns:android="http://schemas.android.com/apk/res/android"
android:drawable="@drawable/ic_vector_arrows">
<target
android:name="left"
android:animation="@animator/vector_left_anim" />
<target
android:name="right"
android:animation="@animator/vector_right_anim" />
</animated-vector>
4、為ImageView設置appCompat
<ImageView
android:layout_width="100dp"
android:layout_height="100dp"
android:onClick="animatorStart"
app:srcCompat="@drawable/anim" />
5、使用動畫
public void animatorStart(View view) {
ImageView imageView = (ImageView) view;
AnimatedVectorDrawable drawable = (AnimatedVectorDrawable)imageView.getDrawable();
drawable.start();
}
我們此時會發(fā)現,創(chuàng)建一個Vector動畫步驟也太繁瑣了吧,沒關系,谷歌工程師早就幫我們想好了解決辦法,通過合并資源,輕松完成上面前3步。
2.2、軌跡動畫
這是一種比較常見的動畫,比如以下幾種(請原諒我盜圖):
看起來是不是很炫酷,其實實現起來很簡單:
將objectAnimator動畫文件android:valueType
屬性設置為floatType
,android:propertyName
屬性設置為trimPathStart
,trimPathEnd
,trimPathOffset
之一,并指定android:valueTo
和android:valueTo
。
當動畫執(zhí)行后,會不斷修改上述3個屬性的值,以實現各種軌跡動畫效果。這3個屬性含義上文已經解釋,這里就不再提及。
知道了上面的內容,就能很好理解屬性動畫的定義產生的不同效果了:
1、使用trimPathStart屬性,valueFrom:0,valueTo:1
線條從起點縮短到終點,即初始截斷部分是0%,從起點開始逐漸擴大到終點,達到100%。
2、使用trimPathStart屬性,valueFrom:1,valueTo:0
線條從終點增長到起點,即初始截斷部分是100%,從終點開始逐漸縮小到起點,達到0%。
3、使用trimPathEnd屬性,valueFrom:0,valueTo:1
線條從起點增長到終點,即初始截斷部分是100%,從起點開始逐漸縮小到終點,達到0%。
4、使用trimPathEnd屬性,valueFrom:1,valueTo:0
線條從終點縮短到起點,即初始截斷部分是0%,從終點開始逐漸擴大到起點,達到100%。
2.3、路徑動畫
路徑動畫,相對來說就麻煩一下,但麻煩的在于制作,不是使用,使用時,只需將propertyName設置為pathData,valueType設置為pathType即可。Android就可以從一種圖像變成另一種圖像。
3、兼容性
3.1、VectorDrawable
Android L,只兼容minSDK>=21的版本
Gradle Plugin 1.5
設備版本>=21——使用Vector
設備版本<21——將Vector轉換為png
AppCompat23.2后,VectorDrawable幾乎可以兼容大部分使用場景
靜態(tài)Vector支持Android2.1+
動態(tài)Vector支持Android3.0+
3.1、AnimatedVectorDrawable兼容性
1、向下兼容問題
Path Morphing
路徑變換動畫,在Android pre-L版本下是無法使用的
Path Interpolation
路徑插值器,在Android pre-L版本下只能使用系統(tǒng)的插值器,不能自定義
2、向上兼容問題
Path Morphing
路徑變換動畫,在Android L版本以上需要使用代碼配置