五、Android SVG動畫

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、軌跡動畫

這是一種比較常見的動畫,比如以下幾種(請原諒我盜圖):


451f72f752ee777e3df07be3223b47ea.gif
19101361568977583839781636.gif

看起來是不是很炫酷,其實實現起來很簡單:
將objectAnimator動畫文件android:valueType屬性設置為floatTypeandroid:propertyName屬性設置為trimPathStart,trimPathEndtrimPathOffset之一,并指定android:valueToandroid: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版本以上需要使用代碼配置

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯(lián)系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發(fā)布,文章內容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市,隨后出現的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 229,908評論 6 541
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機,發(fā)現死者居然都...
    沈念sama閱讀 99,324評論 3 429
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事?!?“怎么了?”我有些...
    開封第一講書人閱讀 178,018評論 0 383
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 63,675評論 1 317
  • 正文 為了忘掉前任,我火速辦了婚禮,結果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當我...
    茶點故事閱讀 72,417評論 6 412
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 55,783評論 1 329
  • 那天,我揣著相機與錄音,去河邊找鬼。 笑死,一個胖子當著我的面吹牛,可吹牛的內容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 43,779評論 3 446
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 42,960評論 0 290
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后,有當地人在樹林里發(fā)現了一具尸體,經...
    沈念sama閱讀 49,522評論 1 335
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 41,267評論 3 358
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現自己被綠了。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 43,471評論 1 374
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 39,009評論 5 363
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響,放射性物質發(fā)生泄漏。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 44,698評論 3 348
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 35,099評論 0 28
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 36,386評論 1 294
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個月前我還...
    沈念sama閱讀 52,204評論 3 398
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 48,436評論 2 378

推薦閱讀更多精彩內容

  • 在完成矢量圖動畫之前,必須了解矢量圖在Android中的代碼表示。Android Studio也可以制作自帶的矢量...
    NoBugException閱讀 1,402評論 1 10
  • SVG是什么,使用它的優(yōu)勢 SVG是指可伸縮矢量圖形 (Scalable Vector Graphics),它不同...
    黃海佳閱讀 4,235評論 0 4
  • 導語 黑科技來了,Google在Android5.X中增加了對SVG矢量圖形的支持,這對于創(chuàng)造新的高效率動畫具有很...
    一個有故事的程序員閱讀 17,355評論 9 64
  • 久違的晴天,家長會。 家長大會開好到教室時,離放學已經沒多少時間了。班主任說已經安排了三個家長分享經驗。 放學鈴聲...
    飄雪兒5閱讀 7,547評論 16 22
  • 今天感恩節(jié)哎,感謝一直在我身邊的親朋好友。感恩相遇!感恩不離不棄。 中午開了第一次的黨會,身份的轉變要...
    迷月閃星情閱讀 10,594評論 0 11