看完本文,每人送一臺小黃車,掘金牌的~html
不得不說,矢量圖在項目中用得少之又少,卻很香!可縮放矢量圖形(SVG)是一套語法規範,常在前端中使用,而VectorDrawable(Android中的矢量圖)只實現了SVG的部分語法。使用VectorDrawable
代替位圖能夠減少 APK 的大小,由於能夠針對不一樣的屏幕密度調整同一文件的大小,而不會下降圖片質量,同時能夠實現一些複製的效果圖。前端
能夠從下面兩個地方得到經常使用矢量圖:android
Vector Asset Studio
工具
「Android版本兼容問題」web
因爲兼容低版本問題,致使矢量圖得不到推廣吧?可是如今大多數手機系統都Android 5.0起步了吧。app
矢量圖VectorDrawable
僅支持到Android 4.4,經過支持庫可最低支持到Android 2.1。編輯器
矢量圖動畫AnimatedVectorDrawable
僅支持到Android 5.0,經過支持庫最低支持到Android 3.0。 「Gralde配置」工具
android {
defaultConfig { vectorDrawables.useSupportLibrary = true } } dependencies { //須要 Android 支持庫 23.2 或更高版本以及 Android Plugin for Gradle 2.0 或更高版本 implementation 'com.android.support:appcompat-v7:23.2.0' } 複製代碼
「美圖減壓鑑賞:」 佈局
經過Android Studio的Vector Asset Studio
工具來獲取一張矢量圖。post
根據我的喜愛配置Vector Assert。 會在drawable文件夾生成資源文件,例如這裏生成ic_menu.xml
文件:flex
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp" android:height="24dp" android:viewportWidth="24" android:viewportHeight="24" android:tint="?attr/colorControlNormal"> <path android:fillColor="@android:color/white" android:pathData="M3,18h18v-2L3,16v2zM3,13h18v-2L3,11v2zM3,6v2h18L21,6L3,6z"/> </vector> 複製代碼
沒了解過矢量圖,相信是看不懂path
標籤pathData
屬性的內容。
在vector
標籤設置矢量圖大小,width
和height
屬性分別爲24dp
。viewportWidth
和viewportHeight
屬性表示畫布的大小,表示將矢量圖等分的份數,這裏劃分爲24*24。能夠理解在一張24dp*24dp的圖片上有24*24個小方格,經過這些小方格,能夠繪製不一樣圖案。
path
能夠理解爲路徑,圖片繪製的內容。fillColor
屬性表示填充顏色,pathData
屬性表示在圖片上做畫內容。
pathData
屬性的值是SVG的語法內容,經過下面的內容就能夠了解pathData
屬性值的含義了。
經常使用命令:
「M x,y」 移動到座標(x,y)。M3,18表示將畫筆移動到座標(3,18)
「L x,y」從當前的位置畫一條直線到指定的位置(x,y)。
「H x」 畫水平線到x位置。
「V y」 畫垂直線到y位置。
「Z」 閉合,鏈接終點和起點
「A rx,ry,xRotationAnagle,radianFlag,sweepFlag,x,y」 畫弧線,理解爲橢圓的一部分,rx
和ry
表示 x軸和y軸半徑,即橢圓的長短軸問題;xRotationAnagle
表示x軸旋轉角度(搞不明白用法);radianFlag
0表示取小弧度,1表示取大弧度;sweepFlag
0表示逆時針,表示1順時針畫弧線;x
和y
弧線的終點位置,起點位置爲畫筆所在的地方。
「C x1,y1,x2,y2,x3,y3」 三次貝賽曲線
「S x2,y2,x,y」 光滑三次貝塞爾曲線
「Q x1,y1,x2,y2」 二次貝賽曲線
「T x,y」 映射
ps:大寫表示絕對座標,小寫表示相對座標。
對pathData
標籤內容進行解讀:
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp" android:height="24dp" android:viewportWidth="24" android:viewportHeight="24" android:tint="?attr/colorControlNormal"> <path android:fillColor="@android:color/white" android:pathData="M3,18 h18 v-2 L3,16 v2 z M3,13 h18 v-2 L3,11 v2 z M3,6 v2 h18 L21,6 L3,6 z"/> </vector> 複製代碼
M3,18
將畫筆移動到座標(3,18)
;
h18
從座標(3,18)
到座標(21,18)
畫一條水平直線;
v-2
從座標(21,18)
到座標(21,16)
畫一條垂直直線;
L3,16
從座標(21,18)
到座標(3,16)
畫一條直線;
v2
從座標(3,16)
到座標(3,18)
畫一條垂直直線;
z
閉合起點和終點。
到這裏,最底部的直線就會畫出來了,其餘兩條線是相同原理。
「注意事項」:不要將pathData的值抽離出來放到string.xml
文件,否則在兼容5.0如下機型生成png圖片,會報pathData錯誤。
那path
標籤除了pathData
屬性,還有哪些可用的屬性呢?
path
標籤path
標籤可用屬性:
name
:路徑名稱,可在其餘地方引用,例如矢量圖動畫引用;
strokeWidth
:線條寬度,單位爲
viewportHeight
或
viewportWidth
中的1等分;。
strokeColor
:線條顏色;
strokeAlpha
:線條透明度。
0f->1f
;
strokeLineJoin
:線條拐角的形狀。圓角
round
、斜切尖角
miter
、斜角
bevel
,例如正方形的四個角;
strokeLineCap
:線條線帽形狀。圓角
round
、正方形
square
、臂
butt
;
strokeMiterLimit
:斜線miter與strokeWidth的比例上限。若是比例值超過這個值,再也不顯示尖角而是bevel斜角。當
strokeLineJoin
屬性設置爲
miter
才生效。
fillColor
:填充顏色;
fillType
:填充類型,取值
nonZero
、
evenOdd
;
fillAlpha
:填充透明度;
trimPathStart
:從路徑開始位置剪掉比率的內容,留下剩下的,
0f->1f
;
trimPathEnd
:從路徑開始位置截取比率的內容,留下截取的內容,
0f->1f
;
trimPathOffset
:
trimPathStart
或
trimPathEnd
的偏移量
0f->1f
;
例如:
XML佈局以下:
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp" android:height="24dp" android:viewportWidth="24" android:viewportHeight="24"> <path android:name="triangle" android:pathData="M3,18 h18 v-5 L3,13 v5 z " android:strokeWidth="1" android:strokeLineJoin="round" android:strokeAlpha="0.9" android:strokeColor="@color/white" android:trimPathStart="0.1" android:strokeLineCap="round" android:trimPathOffset="0.15" /> </vector> 複製代碼
PreView效果以下:
group
標籤group
標籤主要是將多個path
標籤組合起來,子標籤也能夠是group
標籤,其屬性做用於全部子標籤,有如下屬性:
name
: 定義
group
標籤名稱;
translateX
: x軸位移;
translateY
: y軸位移;
rotation
: 旋轉;
scaleX
: x軸縮放;
scaleY
: y軸縮放;
pivotX
: 縮放與旋轉參考點X;
pivotY
: 縮放與旋轉參考點y; 栗子:
XML佈局代碼:
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp" android:height="24dp" android:viewportWidth="24" android:viewportHeight="24"> <group android:name="triangleGroup" android:rotation="10" android:translateX="1" android:translateY="1" android:scaleX="0.5f" android:scaleY="0.5f" android:pivotX="0.5" android:pivotY="0.5"> <path android:fillColor="@color/colorPrimary" android:pathData="M6,6 L9,12 H3 z" android:strokeWidth="0.5" android:strokeColor="@color/white" android:strokeLineJoin="round" /> <path android:fillColor="@color/chart_color_1" android:pathData="M18,6 L21,12 H15 z" android:strokeWidth="0.5" android:strokeColor="@color/white" android:strokeLineJoin="bevel" /> </group> </vector> 複製代碼
效果圖:
只要膽子大,沒有實現不了的矢量圖,加上點動畫效果那就更炫酷吊了。屬性動畫了解多少呢?好文連接==>:Android屬性動畫,看完這篇夠用了吧
「矢量圖動畫步驟」
軌跡動畫主要利用屬性動畫設置矢量圖的trimPathStart
或trimPahtEnd
屬性。要正確實現軌跡動畫的前提條件:矢量圖是一筆畫出的,不能存在屢次挪畫筆的操做。
示例:
vector_text.xml
文件:
<?xml version="1.0" encoding="utf-8"?>
<vector xmlns:android="http://schemas.android.com/apk/res/android" android:width="240dp" android:height="240dp" android:viewportWidth="24" android:viewportHeight="24"> <path android:name="pathText" android:pathData="M9,6 L12,12 L15,6.5 18,12 21,6" android:strokeWidth="0.5" android:strokeColor="@color/white" android:strokeLineCap="round" android:strokeLineJoin="round" /> </vector> 複製代碼
畫了一個白色的W
:
2. 在animator
文件夾下建立animator_text.xml
文件。定義一個屬性動畫,操做矢量圖的trimPathEnd
屬性。
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android"> <objectAnimator android:duration="2000" android:propertyName="trimPathEnd" android:valueFrom="0" android:valueTo="1" android:repeatMode="reverse" android:repeatCount="infinite" android:valueType="floatType" /> //這裏順便操做矢量圖的畫筆顏色 <objectAnimator android:duration="2000" android:propertyName="strokeColor" android:valueFrom="@color/white" android:repeatMode="reverse" android:repeatCount="infinite" android:valueTo="@android:color/holo_blue_dark" android:valueType="colorType" /> </set> 複製代碼
drawable
文件夾下建立
animator_vector_text.xml
文件,組合矢量圖和屬性動畫,成爲它兩的粘合劑。因爲兼容問題,須要在
drawable-v21
文件夾下建立。
<animated-vector xmlns:android="http://schemas.android.com/apk/res/android"
android:drawable="@drawable/vector_text"> <target android:name="pathText" android:animation="@animator/animator_text" /> </animated-vector> 複製代碼
animated-vector
標籤的drawable
屬性值是第一步定義的矢量圖文件名。target
標籤的name
屬性是咱們在矢量圖中定義的;而animation
屬性則是第二部定義的屬性動畫文件名。
animator_vector_text
文件
<ImageView
android:id="@+id/iv" app:srcCompat="@drawable/vector_animator_text" android:layout_width="match_parent" android:layout_height="wrap_content" /> 複製代碼
val animatable = iv.drawable as Animatable animatable.start() 複製代碼
「效果圖:」
路徑動畫是利用矢量圖中相同的關鍵點進行變幻的過程。
Android 5.0前不支持路徑動畫。
示例:
vector_line.xml
文件:
<?xml version="1.0" encoding="utf-8"?>
<vector xmlns:android="http://schemas.android.com/apk/res/android" android:width="240dp" android:height="240dp" android:viewportWidth="24" android:viewportHeight="24"> <path android:name="pathLine" android:pathData="M9,6 L12,6 L15,6 18,6 21,6" android:strokeWidth="0.5" android:strokeColor="@color/white" android:strokeLineCap="round" android:strokeLineJoin="round" /> </vector> 複製代碼
咱們定義了幾個關鍵點,畫了一條直線:
2. 在animator
文件夾下建立animator_morphing.xml
文件。定義一個屬性動畫,操做矢量圖的pathData
屬性。valueFrom
是第一步建立直線矢量圖的屬性pathData
的值,valueTo
是W
矢量圖的pathData
的值。
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android"> <objectAnimator android:duration="2000" android:propertyName="pathData" android:valueFrom="M9,6 L12,6 L15,6 18,6 21,6" android:valueTo="M9,6 L12,12 L15,6.5 18,12 21,6" android:valueType="pathType" /> </set> 複製代碼
drawable
文件夾下建立
animator_vector_line.xml
文件,組合矢量圖和屬性動畫,成爲它兩的粘合劑。因爲兼容問題,須要在
drawable-v21
文件夾下建立。
<?xml version="1.0" encoding="utf-8"?>
<animated-vector xmlns:android="http://schemas.android.com/apk/res/android" android:drawable="@drawable/vector_line"> <target android:name="pathLine" android:animation="@animator/animator_morphing" /> </animated-vector> 複製代碼
animator_vector_text
文件
<ImageView
android:id="@+id/iv" app:srcCompat="@drawable/vector_animator_line" android:layout_width="match_parent" android:layout_height="wrap_content" /> 複製代碼
val animatable = iv.drawable as Animatable animatable.start() 複製代碼
「效果圖」
到這裏就結束了,下面是屬於你們的小黃車~
實例demo演示,用了2小時給你們製做的小黃車,但願不要嫌棄:
<?xml version="1.0" encoding="utf-8"?>
<vector xmlns:android="http://schemas.android.com/apk/res/android" android:width="300dp" android:height="300dp" android:viewportWidth="200" android:viewportHeight="200"> <!--左車輪--> <group android:name="leftWheel" android:pivotX="40" android:pivotY="70"> <path android:name="leftWheelAxle" android:pathData="M 40,70 L23,80M 40,70 L40,50 M 40,70 L57,80" android:strokeWidth="1" android:strokeColor="@color/white" /> <path android:pathData="M 60,70 A 20,20,0,1,1,60,69 z" android:strokeWidth="1" android:strokeColor="@color/white" /> </group> <!--右車輪--> <group android:name="rightWheel" android:pivotX="130" android:pivotY="70"> <path android:name="rightWheelAxle" android:pathData="M 130,70 L113,80 M 130,70 L130,50 M 130,70 L147,80" android:strokeWidth="1" android:strokeColor="@color/white" /> <path android:pathData="M 150,70 A 20,20,0,1,1,150,69 z" android:strokeWidth="1" android:strokeColor="@color/white" /> </group> <!--車鏈盒子--> <path android:name="chainBox" android:fillColor="@color/colorPrimary" android:pathData="M 35,62 h54 v12 H35 z" android:strokeWidth="1" android:strokeColor="@color/white" /> <!--車架--> <path android:pathData="M 50,69 L 65,40 L 80,69 M 86,65 L110,31 v 20 L130,70 " android:strokeWidth="2" android:strokeColor="@color/colorPrimary" android:strokeLineJoin="round" /> <!--前車輪擋板--> <path android:pathData="M105,73 A 20,20,0,1,1,125,85" android:strokeWidth="2" android:strokeColor="@color/colorPrimary" android:strokeLineJoin="round" android:trimPathEnd="0.4" /> <!--車把--> <path android:pathData="M 110,31 V20 l -10,-4 h -3 M110,21 l -4,-10 h-3" android:strokeWidth="2" android:strokeColor="@color/white" android:strokeLineCap="round" android:strokeLineJoin="round" /> <!--車籃--> <path android:fillColor="@color/white" android:pathData="M 111,41 h 21 v -12 H 111 z" android:strokeWidth="1" android:strokeColor="@color/white" android:strokeLineCap="square" android:strokeLineJoin="round" /> <!--掘金LOGO--> <path android:fillColor="@color/colorPrimary" android:pathData="M 121,30 L122,31 L121,32 L120,31 z" android:strokeWidth="0.5" android:strokeColor="@color/colorPrimary" android:strokeLineCap="square" android:strokeLineJoin="miter" /> <path android:pathData=" M119,33 L121,35,L123,33 M118,34 L121,37,L124,34" android:strokeWidth="0.5" android:strokeColor="@color/colorPrimary" android:strokeLineCap="square" android:strokeLineJoin="miter" /> <!--皮座--> <path android:fillColor="@color/white" android:pathData="M 55,40 h 20 v-4 H56 v-3h-2" android:strokeWidth="1" android:strokeColor="@color/white" android:strokeLineCap="square" android:strokeLineJoin="round" /> <!--腳踏板--> <group android:name="pedal" android:pivotX="82" android:pivotY="68"> <path android:pathData="M 82,68 L 98,80" android:strokeWidth="0.5" android:strokeColor="@color/white" android:strokeLineCap="round" /> <path android:fillColor="@color/white" android:pathData="M 96,80 A 2,2,0,1,1,96,81 z" android:strokeWidth="1" android:strokeColor="@color/white" /> </group> </vector> 複製代碼
「預覽圖:」
2. 在animator
文件夾下建立animator_wheel.xml
文件,實現車輪和腳踏旋轉屬性動畫:
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android"> <objectAnimator android:interpolator="@android:interpolator/linear" android:propertyName="rotation" android:repeatCount="infinite" android:valueType="floatType" android:valueFrom="0f" android:valueTo="360f" android:repeatMode="restart" android:duration="2000"/> //能夠再增長其餘動畫效果,例如顏色變化 </set> 複製代碼
animator
文件夾下建立
animator_bicycle_left_to_right.xml
佈局文件,實現單車從左到右移動屬性動畫:
<objectAnimator xmlns:android="http://schemas.android.com/apk/res/android"
android:propertyName="translationX" android:valueFrom="-600f" android:valueTo="900f" android:valueType="floatType" android:repeatCount="infinite" android:repeatMode="restart" android:duration="9000" android:interpolator="@android:interpolator/linear" /> 複製代碼
drawable
文件夾下建立
verctor_animator_bicycle.xml
文件,實現單車矢量圖和屬性動畫的粘合劑,也就是最終的矢量圖動畫。因爲兼容問題,須要在drawable-v21文件夾下建立。
<?xml version="1.0" encoding="utf-8"?>
<animated-vector xmlns:android="http://schemas.android.com/apk/res/android" android:drawable="@drawable/vertor_bicycle"> <target android:animation="@animator/animator_wheel" android:name="leftWheel"/> <target android:animation="@animator/animator_wheel" android:name="rightWheel"/> <target android:animation="@animator/animator_wheel" android:name="pedal"/> </animated-vector> 複製代碼
verctor_animator_bicycle.xml
文件,
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" xmlns:app="http://schemas.android.com/apk/res-auto" android:background="@color/black"> <ImageView android:id="@+id/iv" app:srcCompat="@drawable/verctor_animator_bicycle" android:layout_width="match_parent" android:layout_height="wrap_content" /> <TextView android:id="@+id/btnStart" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignParentBottom="true" android:layout_centerHorizontal="true" android:layout_marginBottom="50dp" android:background="@color/white" android:padding="10dp" android:text="開始" android:textColor="@color/colorPrimary" android:textSize="16sp" /> </RelativeLayout> 複製代碼
AppCompatActivity
中代碼調用:
btnStart.setOnClickListener { val animatable = iv.drawable as Animatable animatable.start() } 複製代碼
此時效果圖: 7. 加上從左到右的屬性動畫:
btnStart.setOnClickListener { val animatable = iv.drawable as Animatable animatable.start() val animator = AnimatorInflater.loadAnimator(this, R.animator.animator_bicycle_left_to_right) animator.setTarget(iv) animator.start() } 複製代碼
效果圖:
好了哇,你們的小黃車已經造好,請給文章點個贊領取,若是不滿意,能夠自行定製小黃車哦~
「要啥自行車,想要個贊而已」
參考文章:
本文使用 mdnice 排版