Android矢量圖動畫:每人送一輛掘金牌小黃車

看完本文,每人送一臺小黃車,掘金牌的~html

不得不說,矢量圖在項目中用得少之又少,卻很香!可縮放矢量圖形(SVG)是一套語法規範,常在前端中使用,而VectorDrawable(Android中的矢量圖)只實現了SVG的部分語法。使用VectorDrawable代替位圖能夠減少 APK 的大小,由於能夠針對不一樣的屏幕密度調整同一文件的大小,而不會下降圖片質量,同時能夠實現一些複製的效果圖。前端

能夠從下面兩個地方得到經常使用矢量圖:android

  • IconFont
  • Android Stuido 自帶的 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標籤設置矢量圖大小,widthheight屬性分別爲24dpviewportWidthviewportHeight屬性表示畫布的大小,表示將矢量圖等分的份數,這裏劃分爲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 畫弧線,理解爲橢圓的一部分,rxry表示 x軸和y軸半徑,即橢圓的長短軸問題;xRotationAnagle表示x軸旋轉角度(搞不明白用法);radianFlag 0表示取小弧度,1表示取大弧度;sweepFlag 0表示逆時針,表示1順時針畫弧線;xy弧線的終點位置,起點位置爲畫筆所在的地方。

  • 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:線條寬度,單位爲 viewportHeightviewportWidth中的1等分;。
  • strokeColor:線條顏色;
  • strokeAlpha:線條透明度。 0f->1f
  • strokeLineJoin:線條拐角的形狀。圓角 round、斜切尖角 miter、斜角 bevel,例如正方形的四個角;
  • strokeLineCap:線條線帽形狀。圓角 round、正方形 square、臂 butt
  • strokeMiterLimit:斜線miter與strokeWidth的比例上限。若是比例值超過這個值,再也不顯示尖角而是bevel斜角。當 strokeLineJoin屬性設置爲 miter才生效。
  • fillColor:填充顏色;
  • fillType:填充類型,取值 nonZeroevenOdd;
  • fillAlpha:填充透明度;
  • trimPathStart:從路徑開始位置剪掉比率的內容,留下剩下的, 0f->1f;
  • trimPathEnd:從路徑開始位置截取比率的內容,留下截取的內容, 0f->1f;
  • trimPathOffsettrimPathStarttrimPathEnd的偏移量 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屬性動畫,看完這篇夠用了吧

矢量圖動畫步驟

  1. 實現矢量圖
  2. 實現屬性動畫
  3. 實現矢量屬性動畫粘合劑
  4. 佈局引用,代碼開始動畫

軌跡動畫

軌跡動畫主要利用屬性動畫設置矢量圖的trimPathStarttrimPahtEnd屬性。要正確實現軌跡動畫的前提條件:矢量圖是一筆畫出的,不能存在屢次挪畫筆的操做。

示例:

  1. 在drawable文件夾下建立 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> 複製代碼
  1. 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屬性則是第二部定義的屬性動畫文件名。

  1. 在佈局在引用 animator_vector_text文件
<ImageView
 android:id="@+id/iv"  app:srcCompat="@drawable/vector_animator_text"  android:layout_width="match_parent"  android:layout_height="wrap_content" /> 複製代碼
  1. 在代碼中開始動畫:
val animatable = iv.drawable as Animatable
 animatable.start() 複製代碼

效果圖:

路徑動畫

路徑動畫是利用矢量圖中相同的關鍵點進行變幻的過程。

Android 5.0前不支持路徑動畫。

示例:

  1. 在drawable文件夾下建立 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的值,valueToW矢量圖的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> 複製代碼
  1. 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> 複製代碼
  1. 在佈局在引用 animator_vector_text文件
<ImageView
 android:id="@+id/iv"  app:srcCompat="@drawable/vector_animator_line"  android:layout_width="match_parent"  android:layout_height="wrap_content" /> 複製代碼
  1. 在代碼中開始動畫效果:
val animatable = iv.drawable as Animatable
 animatable.start() 複製代碼

效果圖

到這裏就結束了,下面是屬於你們的小黃車~

你們的小黃車

實例demo演示,用了2小時給你們製做的小黃車,但願不要嫌棄:

  1. 在drawable文件夾下建立vertor_bicycle.xml文件夾,內容以下:
<?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> 複製代碼
  1. 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"  /> 複製代碼
  1. 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> 複製代碼
  1. 在佈局中引用 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> 複製代碼
  1. 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()  } 複製代碼

效果圖:

好了哇,你們的小黃車已經造好,請給文章點個贊領取,若是不滿意,能夠自行定製小黃車哦~

要啥自行車,想要個贊而已

參考文章:

Android屬性動畫,看完這篇夠用了吧

官網

Android 5.0+ 高級動畫開發系列 矢量圖動畫

Android Vector曲折的兼容之路

本文使用 mdnice 排版

相關文章
相關標籤/搜索