Android資源res之向量圖完全指南(附贈SVG-path命令分析)
零、前言
第一次接觸SVG時,被它的強大折服,下面兩個小例子可以看看
ofollow,noindex">SVG 文字sin型曲線動畫 、 SVG繪製星空效果
Android5.0+也支援向量圖VectorDrawable,是變異削弱版的SVG,但已經非常強大了
本來不想寫SVG的path的,但是發現需要用到,還是總結一下吧
留圖鎮樓
手撕路徑動畫:
path變形 | 變形+旋轉 |
---|---|
![]() |
![]() |
常規動畫

一、SVG的Path
1.
SVG中的Path(有點反人類,可忽略)
命令 含義 M/m (x,y)+ 移動當前位置 L/l (x,y)+ 從當前位置繪製線段到指定位置 H/h (x)+ 從當前位置繪製,水平線到達指定的 x 座標 V/v (x)+ 從當前位置繪製豎直線到達指定的 y 座標 Z/z 閉合當前路徑 C/c (x1,y1,x2,y2,x,y)+ 從當前位置繪製三次貝塞爾曲線到指定位置 S/s (x2,y2,x,y)+ 從當前位置光滑繪製三次貝塞爾曲線到指定位置 Q/q (x1,y1,x,y)+ 從當前位置繪製,二次貝塞爾曲線到指定位置 T/t (x,y)+ 從當前位置光滑繪製,二次貝塞爾曲線到指定位置 A/a (rx,ry,xr,laf,sf,x,y)從當前位置繪製弧線到指定位置
2.一開始覺得挺好玩,但是看到...
:Iconfont-阿里巴巴向量圖示庫 ![]()
劍.png
3.SVG轉為Android可用Xml
下載的svg在Android可不能直接用哦,你有3種選擇:
3.1--AS自帶的轉換
![]()
AS自帶轉換.png
3.2--網上線上轉換:網址
![]()
線上轉換.png
3.3--批量轉化:
前兩者都是單檔案的轉化,如果很多檔案就有一個一個來
so,我自己寫了工具類,
批量轉化一下
:詳情可見:第三個工具工具現在已經使用正則匹配了,更加精確,轉換1000+,暫無失誤情況
![]()
svg2xml.png
二、VectorDrawable的使用
![]()
向量劍.png
1.修改顏色:兩種方法
方法1:直接改:fillColor 方法2:使用時:android:tint="@color/red"2.分組與變換(吾王之劍豈可不正)
用group將path包起來就可以對path進行變換了
![]()
group變換.png
<group android:rotation="-45" android:scaleX="0.7" android:scaleY="0.7" android:translateY="450"> <path ... <path ... </group>三、向量動畫
向量動畫最好是針對線條,即:strokeColor。使用fillColor的填充有些動畫看起來怪怪的。
動畫基本套路如下--簡單畫一個示意圖:
![]()
向量動畫--路徑動畫.png
1:路徑動畫:trimPathEnd
![]()
路徑動畫.gif
1.1--向量圖主體:icon_close.xml
記得為path取個名字(隨意):
android:name="trim_path"
<?xml version="1.0" encoding="utf-8"?> <vector xmlns:android="http://schemas.android.com/apk/res/android" android:width="48dp" android:height="48dp" android:viewportWidth="1024" android:viewportHeight="1024"> <path android:strokeColor="@color/black" android:strokeWidth="10" android:name="trim_path" android:pathData="M548.992 503.744L885.44 167.328a31.968 31.968 0 1 0-45.248-45.248L503.744 458.496 167.328 122.08a31.968 31.968 0 1 0-45.248 45.248l336.416 336.416L122.08 840.16a31.968 31.968 0 1 0 45.248 45.248l336.416-336.416L840.16 885.44a31.968 31.968 0 1 0 45.248-45.248L548.992 503.744z" /></vector>1.2--objectAnimator動畫:trim_path_animator.xml
<?xml version="1.0" encoding="utf-8"?> <objectAnimator xmlns:android="http://schemas.android.com/apk/res/android" android:duration="2000" android:interpolator="@android:interpolator/linear" android:propertyName="trimPathEnd" android:valueFrom="0.0" android:valueTo="1.0" android:valueType="floatType"/>1.3--動畫承載體:anima_close.xml
<animated-vector xmlns:android="http://schemas.android.com/apk/res/android" android:drawable="@drawable/icon_close"> <target android:animation="@animator/trim_path_animator" android:name="trim_path"/> </animated-vector>1.4--使用
<ImageView android:id="@+id/id_iv" android:layout_width="200dp" android:layout_height="200dp" android:src="@drawable/anima_close" app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintEnd_toEndOf="parent" app:layout_constraintStart_toStartOf="parent" app:layout_constraintTop_toTopOf="parent"/>//點選時: Drawable drawable = mIdIv.getDrawable(); if (drawable instanceof Animatable){ ((Animatable) drawable).start(); }2.常規動畫
非要平移或縮放還是針對View吧,向量圖是有邊界的,超出邊界不顯示
![]()
常規動畫.gif
2.1:--顏色動畫:color_animator.xml
<?xml version="1.0" encoding="utf-8"?> <set xmlns:android="http://schemas.android.com/apk/res/android" android:ordering="sequentially"> <objectAnimator android:duration="2000" android:propertyName="strokeColor" android:valueFrom="@color/black" android:valueTo="@color/red"/> <objectAnimator android:duration="2000" android:propertyName="strokeColor" android:valueFrom="@color/red" android:valueTo="@color/black"/> </set>2.2:--透明度動畫:alpha_animator.xml
<?xml version="1.0" encoding="utf-8"?> <set xmlns:android="http://schemas.android.com/apk/res/android" android:ordering="sequentially"> <objectAnimator android:duration="1500" android:propertyName="strokeAlpha" android:valueFrom="1f" android:valueTo="0.5f"/> <objectAnimator android:duration="1500" android:propertyName="strokeAlpha" android:valueFrom="0.5f" android:valueTo="1f"/> </set>2.3:--旋轉動畫:rotation_animator_360.xml
<?xml version="1.0" encoding="utf-8"?> <set xmlns:android="http://schemas.android.com/apk/res/android" android:ordering="sequentially"> <objectAnimator android:duration="1500" android:propertyName="rotation" android:valueFrom="0" android:valueTo="360"/> <objectAnimator android:duration="1500" android:propertyName="rotation" android:valueFrom="360" android:valueTo="0"/> </set>2.3:向量圖:icon_setting.xml
<?xml version="1.0" encoding="utf-8"?> <vector xmlns:android="http://schemas.android.com/apk/res/android" android:width="48dp" android:height="48dp" android:viewportWidth="1024" android:viewportHeight="1024"> <group android:name="container" android:pivotX="512" android:pivotY="512"> <path android:name="setting_path" android:pathData="M514.216481 977.624786c-55.577806 0.002047-89.432869-13.881149-91.457991-14.734586-6.476505-2.729158-10.8143-8.92937-11.160177-15.94925-0.354064-7.203052-0.674359-14.411221-0.994654-21.620413-0.618077-13.917988-1.257643-28.307719-2.143826-42.354644-0.528026-8.348132-1.026376-8.606005-2.88163-9.564843-6.768147-3.497661-14.646582-6.115278-22.98755-8.885368-7.208169-2.39556-14.662955-4.871961-22.014386-8.124028-4.52199-2.001587-8.719592-4.269233-12.780071-6.462179-4.65809-2.51631-9.058306-4.89345-13.099343-6.385431-4.536316-1.684362-10.599406 3.223415-21.657252 14.137998-2.720971 2.686179-5.535063 5.464455-8.398274 7.985882l-28.677133 25.26236c-5.973038 5.26184-14.663978 6.053879-21.490453 1.958608-94.435813-56.662511-123.892705-127.005602-125.100206-129.972167-2.650363-6.509251-1.333368-13.96199 3.38612-19.168572l27.558659-30.40345c2.249227-2.480494 4.53734-4.933359 6.749728-7.306406 4.301979-4.612041 8.368598-8.971325 12.106736-13.455453 0.12996-0.706081 0.50142-4.331655-3.148713-12.644995-1.414209-3.219321-2.916423-6.41306-4.50664-9.792017-2.321882-4.931313-4.721535-10.032494-6.912433-15.399735-2.28095-5.586229-3.906983-11.44875-5.480828-17.116843-3.557012-12.81691-6.27389-21.336958-11.419074-22.917966-15.532765-4.774747-32.260751-5.204535-49.971112-5.658883-6.92369-0.178055-14.081717-0.36225-21.279652-0.818645-7.943926-0.503467-14.648628-6.088672-16.579607-13.81054-26.709315-106.838284 2.204202-177.410596 3.447519-180.362834 2.729158-6.477528 8.930393-10.816347 15.951297-11.160177l74.987878-3.679809c8.106632-25.620517 18.959817-50.2955 32.389688-73.637114l-51.368948-58.31822c-5.260817-5.973038-6.052856-14.663978-1.957585-21.48943 56.662511-94.430696 127.004579-123.891681 129.971144-125.099183 6.512321-2.650363 13.964036-1.333368 19.171642 3.387144l59.183937 53.647851c20.770046-10.567683 42.865273-19.247366 65.957201-25.908066l3.986801-81.220836c0.343831-7.019881 4.682649-13.220093 11.159154-15.94925 2.952238-1.24434 73.520457-30.162974 180.363857-3.448542 7.721869 1.930979 13.307074 8.635681 13.81054 16.578584l5.41636 85.444021c23.345708 7.106862 45.86663 16.432251 67.231217 27.840068l62.865793-56.979736c5.208629-4.720511 12.663414-6.03546 19.169595-3.387144 2.966565 1.207501 73.314773 30.664394 129.97319 125.100206 4.095271 6.825452 3.303232 15.516392-1.957585 21.48943l-57.280588 65.029062c11.642155 21.230534 21.185508 43.48642 28.489868 66.439178l84.800361 4.163833c7.019881 0.343831 13.221116 4.683672 15.950274 11.160177 1.24434 2.952238 30.156834 73.525574 3.443425 180.362834-1.929955 7.721869-8.634658 13.307074-16.578584 13.81054l-83.734076 5.308913c-6.765077 24.480554-15.841803 47.948035-27.093055 70.049403l54.525847 60.155055c4.719488 5.207605 6.036483 12.659321 3.388167 19.168572-0.437975 1.075495-4.553713 10.937097-14.205537 25.910113-5.470595 8.486278-16.782222 10.930957-25.270547 5.460362-8.486278-5.470595-10.930957-16.784268-5.460362-25.270547 2.444679-3.791349 4.445242-7.161097 6.039553-10.001795l-54.736649-60.387345c-5.262864-5.805216-6.240121-14.3181-2.431376-21.165042 14.670118-26.371624 25.797549-55.164391 33.073256-85.579097 1.867534-7.807826 8.611122-13.484106 16.623609-13.991666l83.375919-5.285377c13.876032-65.705468 4.495384-113.633037-1.193175-133.800355l-85.226057-4.184299c-7.863085-0.385786-14.594393-5.761214-16.711614-13.34289-7.990998-28.617781-19.810185-56.174394-35.133172-81.904405-4.061502-6.820336-3.258207-15.480576 1.988284-21.437242l56.915267-64.615647c-36.648688-56.272631-77.172637-83.529415-95.455025-93.767594l-63.320141 57.391105c-5.900384 5.349845-14.585183 6.262634-21.469987 2.25639-25.765827-14.990413-53.601802-26.530236-82.734306-34.297131-7.588839-2.0241-13.037944-8.66945-13.535271-16.507976l-5.371334-84.723613c-65.210187-13.727653-113.473401-4.379751-133.804449 1.26276l-4.022617 81.945337c-0.393973 8.037047-5.997598 14.870686-13.801331 16.833387-29.217439 7.345292-56.766888 18.160615-81.884962 32.145118-6.848988 3.812839-15.363919 2.835581-21.170159-2.428306l-59.389622-53.833069c-18.325367 10.365068-59.080583 37.884842-95.503121 93.724615l51.191916 58.118676c5.342682 6.064113 6.068206 14.916734 1.785669 21.770839-17.210987 27.544333-30.330796 57.32766-38.993083 88.524173-2.109034 7.593955-8.847505 12.981662-16.718777 13.368472l-75.366502 3.698229c-5.621021 20.255323-14.963807 68.428485-1.318018 133.528156 2.092661 0.061398 4.210905 0.115634 6.367011 0.170892 19.395746 0.49835 39.450501 1.014096 59.774385 7.262404 24.664749 7.579629 31.162744 30.992875 35.906791 48.087205 1.351787 4.870938 2.62785 9.470699 4.100388 13.075807 1.830695 4.483104 3.925403 8.93551 6.14393 13.650905 1.620917 3.443425 3.297093 7.005554 4.90266 10.661827 11.409864 25.983791 5.193279 41.804105-2.031263 50.500161-4.455475 5.365194-9.139148 10.385535-13.667278 15.241123-2.222621 2.382257-4.322445 4.63353-6.39771 6.922666l-19.11229 21.084201c10.365068 18.325367 37.882795 59.080583 93.724615 95.502098l18.455327-16.257266c2.084475-1.835811 4.412496-4.134157 6.877641-6.567579 12.292977-12.135388 32.868595-32.44597 60.013839-22.416546 6.469342 2.390443 12.233626 5.503341 17.807574 8.514931 3.594875 1.942235 6.991228 3.777023 10.197246 5.195326 5.746888 2.542916 12.060687 4.640694 18.744923 6.861268 9.309016 3.091408 18.934235 6.28924 28.244274 11.100826 20.75265 10.722202 21.946848 29.600155 22.588461 39.742143 0.907673 14.389732 1.555425 28.952402 2.180666 43.037189 0.132006 2.966565 0.264013 5.933129 0.398066 8.898671 20.298302 5.630231 68.558445 14.980179 133.775796 1.25355l4.866844-76.765361c0.497327-7.848759 5.957689-14.499226 13.558807-16.515139 32.683377-8.66638 63.733557-22.102391 92.28687-39.934524 6.854105-4.281513 15.703657-3.553942 21.767769 1.786693l59.114352 52.068889c1.155313-0.751107 2.299369-1.50733 3.432169-2.263553 5.502317-4.045129 38.557154-24.867364 98.619088-25.960255 0.112564-0.002047 0.227174-0.00307 0.339738-0.00307 9.942443 0 18.090007 7.966439 18.271132 17.948791 0.184195 10.094916-7.850805 18.427698-17.945721 18.611893-51.03842 0.928139-77.314877 18.622126-77.69043 18.908652-0.285502 0.216941-0.577145 0.424672-0.874927 0.624217-5.347798 3.583618-10.934027 7.126304-16.603143 10.528797-6.825452 4.100388-15.517415 3.307326-21.493523-1.954515l-59.31492-52.244898c-24.545022 14.104229-50.618864 25.367761-77.794807 33.606399l-4.910846 77.467349c-0.503467 7.944949-6.088672 14.648628-13.81054 16.579607C569.595766 974.71962 539.630291 977.623763 514.216481 977.624786zM517.457292 736.938052c-60.94914 0-118.250194-23.734564-161.347758-66.833151-43.097564-43.096541-66.832128-100.397594-66.832128-161.347758 0-60.948117 23.734564-118.247124 66.833151-161.343665 43.097564-43.096541 100.398618-66.831105 161.346735-66.831105s118.250194 23.734564 161.347758 66.831105 66.833151 100.396571 66.833151 161.343665c0 60.94914-23.734564 118.251218-66.833151 161.347758C635.707486 713.202465 578.406432 736.938052 517.457292 736.938052zM517.457292 317.145104c-105.657388 0-191.617156 85.956697-191.617156 191.613062 0 105.658412 85.958744 191.617156 191.617156 191.617156 105.658412 0 191.617156-85.958744 191.617156-191.617156C709.074448 403.101801 623.115704 317.145104 517.457292 317.145104z" android:strokeWidth="8" android:strokeColor="#000"/> </group> </vector>3.4:動畫整合:anima_setting.xml
<animated-vector xmlns:android="http://schemas.android.com/apk/res/android" android:drawable="@drawable/icon_setting"> <target android:name="setting_path" android:animation="@animator/alpha_animator"/> <target android:name="container" android:animation="@animator/rotation_animator_360"/> <target android:animation="@animator/color_animator" android:name="setting_path"/> <target android:animation="@animator/trim_path_animator" android:name="setting_path"/> </animated-vector>使用同上,不贅述了
3.5:路徑轉換動畫
左上角的箭頭是不是很驚豔:,第一次看到還以為是程式碼的效果呢,原來向量圖也可以輕鬆實現
![]()
DrawerLayout與ToolBar結合
注意:對路徑進行
objectAnimator
,前提,path操作符都要一一對應好吧,看來想躲都躲不掉了,那就來看看svg的path吧
四、SVG的path全指南:
1.操作符:M/m,L/l,H/h,V/v
大寫字母都是絕對座標,小寫字母是相對座標(相對尾點)
![]()
mlhv.png
<?xml version="1.0" encoding="utf-8"?> <vector xmlns:android="http://schemas.android.com/apk/res/android" android:width="48dp" android:height="48dp" android:viewportWidth="100" android:viewportHeight="100"> <!--將指標軸平移--> <group android:translateX="4" android:translateY="4"> <path android:strokeColor="@color/black" android:strokeWidth="4" android:pathData="M0,0 L20 20 0,30,60,60 H 0 V100"/> </group> </vector>2.操作符:CSQT/csqt
注:小寫字母也是相對座標,只演示大寫字母,小寫字母自己對應一下就行了
C/c是三次貝塞爾:曾經寫過一篇詳細分析:詳見
S/s是簡化版的三次貝塞爾,根據一點,自動順滑,具體怎麼順滑,看個大概吧...
Q/q是二次貝塞爾,三次的都會了,二次的還遠嗎?
T/t簡易版二次貝塞爾,需要至少兩個才能發揮曲線作用
![]()
cs.png
![]()
qt.png
3.操作符:A/a
![]()
a.png
A(rx, ry, xr, laf, sf, x,y)----繪製弧線--最複雜的命令 rx - (radius-x)弧線所在橢圓的 x 半軸長 ry - (radius-y)弧線所在橢圓的 y 半軸長 xr - (xAxis-rotation)弧線所在橢圓的長軸角度 laf - (large-arc-flag)是否選擇弧長較長的那一段弧 sf - (sweep-flag)是否選擇逆時針方向的那一段弧 x, y- 弧的終點位置![]()
SVG弧線
五、路徑屬性動畫
好了,知識儲備有了,開始畫圖了,畫個箭頭和三橫還不小case
箭頭:M8,50, l100,0 M0,47, l40,40 M0,52 l40 -40 選單:M0,50, l80,0 M0,80, l80,0 M0,20 l80 0
path變形 變形+旋轉 ![]()
![]()
1.將兩個path字串放入string.xml
直接寫也可以,但複用不方便
<resources> <string name="app_name">test</string> <string name="path_from">M8,50, l100,0 M0,47, l40,40 M0,52 l40 -40 </string> <string name="path_to">M0,50, l80,0 M0,80, l80,0 M0,20 l80 0</string> </resources>2.向量圖:path_test.xml
<?xml version="1.0" encoding="utf-8"?> <vector xmlns:android="http://schemas.android.com/apk/res/android" android:width="48dp" android:height="48dp" android:viewportWidth="100" android:viewportHeight="100"> <group android:translateX="4" android:translateY="4"> <path android:pathData="M0,0 A30,50,90,0,1,50,50" android:strokeWidth="4" android:strokeColor="@color/black"/> </group> </vector>3.旋轉動畫:rotation_animator.xml
<?xml version="1.0" encoding="utf-8"?> <objectAnimator xmlns:android="http://schemas.android.com/apk/res/android" android:duration="1000" android:propertyName="rotation" android:valueFrom="0" android:valueTo="180"/>4.路徑動畫:path_animator.xml
<?xml version="1.0" encoding="utf-8"?> <objectAnimator xmlns:android="http://schemas.android.com/apk/res/android" android:duration="1000" android:interpolator="@android:interpolator/linear" android:propertyName="pathData" android:valueFrom="@string/path_from" android:valueTo="@string/path_to" android:valueType="pathType"/>5.整合動畫:anima_path.xml
<animated-vector xmlns:android="http://schemas.android.com/apk/res/android" android:drawable="@drawable/icon_path"> <target android:name="alpha_anim" android:animation="@animator/path_animator"/> <target android:name="container" android:animation="@animator/rotation_animator"> </target> </animated-vector>ok,這樣就行了,你可以隨意定製兩個路徑,但必須保證兩個路徑的指令相同,不然會崩
後記:捷文規範
1.本文成長記錄及勘誤表
專案原始碼 日期 備註 V0.1--github 2018-12-8 Android資源res之向量圖完全指南(附贈SVG-path命令分析) 2.更多關於我
筆名 微信 愛好 張風捷特烈 1981462002 zdl1994328 語言 我的github 我的簡書 我的掘金 個人網站 3.宣告
1----本文由張風捷特烈原創,轉載請註明
2----歡迎廣大程式設計愛好者共同交流
3----個人能力有限,如有不正之處歡迎大家批評指證,必定虛心改正
4----看到這裡,我在此感謝你的喜歡與支援
![]()
icon_wx_200.png