VectorDrawable基礎知識

1、概述

VectorDrawable是用xml文件定義一系列點、線、曲線及其顏色信息的矢量圖。其最主要的優點是縮放不損失圖片質量。我們也可以通過使用多個xml矢量圖文件來做動畫,從而避免適配多分辨率使用多張圖片。 從android 5.0(api 21),系統提供了VectorDrawable與AnimatedVectorDrawable來支持矢量圖。

2、 關於VectorDrawable

VectorDrawable定義一個靜態的drawable對象。類似svg格式,每個矢量圖被定義成由path和gourp對象構成的樹狀結構。
每個path包含了對象的幾何輪廓,group包含了變化的具體規則。所有的path會按照xml中定義的順序依次繪製。
此處插入官網圖

vectordrawable文件說明

android studio中的vector asset studio提供了非常簡單的添加xml文件矢量圖的功能。
如下爲一個矢量電池圖片的xml文件。

<!-- res/drawable/battery_charging.xml -->
<vector xmlns:android="http://schemas.android.com/apk/res/android"
    <!-- intrinsic size of the drawable -->
    android:height="24dp"
    android:width="24dp"
    <!-- size of the virtual canvas -->
    android:viewportWidth="24.0"
    android:viewportHeight="24.0">
   <group
         android:name="rotationGroup"
         android:pivotX="10.0"
         android:pivotY="10.0"
         android:rotation="15.0" >
      <path
        android:name="vect"
        android:fillColor="#FF000000"
        android:pathData="M15.67,4H14V2h-4v2H8.33C7.6,4 7,4.6 7,5.33V9h4.93L13,7v2h4V5.33C17,4.6 16.4,4 15.67,4z"
        android:fillAlpha=".3"/>
      <path
        android:name="draw"
        android:fillColor="#FF000000"
        android:pathData="M13,12.5h2L11,20v-5.5H9L11.93,9H7v11.67C7,21.4 7.6,22 8.33,22h7.33c0.74,0 1.34,-0.6 1.34,-1.33V9h-4v3.5z"/>
   </group>
</vector>

使用矢量圖xml文件必須在AppCompatImageView中使用或者利用StateListDrawable,如下

<android.support.v7.widget.AppCompatImageView
        android:id="@+id/iv_scale_test"
        android:layout_width="20dp"
        android:layout_height="20dp"
        app:srcCompat="@drawable/test_vector_battery"/>

渲染後的圖形如下

vector-battery

3、關於AnimatedVectorDrawable

AnimatedVectorDrawable爲矢量圖增加了動畫信息。動畫矢量圖可以通過三個單獨的資源文件定義,也可以通過一個單獨的文件定義整個drawable。

3.1、利用多個文件定義動畫矢量圖

構建動畫矢量圖時,需要如下文件
- Vecotr Drawable xml文件
- AnimatedVectorDrawable xml文件,其中定義了目標Vector Drawable,要動畫的目標paths及groups,及其通過ObjectAnimator或者AnimatorSet定義的目標對象。
- animator動畫文件
三個示例文件分別如下

VectorDrawable xml文件

<vector xmlns:android="http://schemas.android.com/apk/res/android"
   android:height="64dp"
   android:width="64dp"
   android:viewportHeight="600"
   android:viewportWidth="600" >
   <group
      android:name="rotationGroup"
      android:pivotX="300.0"
      android:pivotY="300.0"
      android:rotation="45.0" >
      <path
         android:name="vectorPath"
         android:fillColor="#000000"
         android:pathData="M300,70 l 0,-70 70,70 0,0 -70,70z" />
   </group>
</vector>

AnimatedVectorDrawable xml文件

<animated-vector xmlns:android="http://schemas.android.com/apk/res/android"
   android:drawable="@drawable/vd" >
     <target
         android:name="rotationGroup"
         android:animation="@anim/rotation" />
     <target
         android:name="vectorPath"
         android:animation="@anim/path_morph" />
</animated-vector>

animator xml文件,如下定義兩個動畫

<objectAnimator
   android:duration="6000"
   android:propertyName="rotation"
   android:valueFrom="0"
   android:valueTo="360" />

 <set xmlns:android="http://schemas.android.com/apk/res/android">
   <objectAnimator
      android:duration="3000"
      android:propertyName="pathData"
      android:valueFrom="M300,70 l 0,-70 70,70 0,0   -70,70z"
      android:valueTo="M300,70 l 0,-70 70,0  0,140 -70,0 z"
      android:valueType="pathType"/>
</set>

在項目中使用如下代碼開始動畫
((AnimatedVectorDrawableCompat) mTestImg.getDrawable()).start(); 或者轉型爲Animatedable對象,然後調用start()方法。

3.2、利用單個文件定義動畫矢量圖

示例代碼如下:

<animated-vector
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:aapt="http://schemas.android.com/aapt">
    <aapt:attr name="android:drawable">
        <vector
            android:width="24dp"
            android:height="24dp"
            android:viewportWidth="24"
            android:viewportHeight="24">
            <path
                android:name="root"
                android:strokeWidth="2"
                android:strokeLineCap="square"
                android:strokeColor="?android:colorControlNormal"
                android:pathData="M4.8,13.4 L9,17.6 M10.4,16.2 L19.6,7" />
        </vector>
    </aapt:attr>
    <target android:name="root">
        <aapt:attr name="android:animation">
            <objectAnimator
                android:propertyName="pathData"
                android:valueFrom="M4.8,13.4 L9,17.6 M10.4,16.2 L19.6,7"
                android:valueTo="M6.4,6.4 L17.6,17.6 M6.4,17.6 L17.6,6.4"
                android:duration="300"
                android:interpolator="@android:interpolator/fast_out_slow_in"
                android:valueType="pathType" />
        </aapt:attr>
    </target>
</animated-vector>

其中aapt標記創建了單獨的資源並且在矢量文件中引用。這種方式需要24版本以上的構建工具。

4、xml矢量文件中的元素

path的可選項釋義

android:name 定義該 path 的名字,這樣在其他地方可以通過名字來引用這個路徑

android:pathData 和 SVG 中 d 元素一樣的路徑信息。

android:fillColor 定義填充路徑的顏色,如果沒有定義則不填充路徑

android:strokeColor 定義如何繪製路徑邊框,如果沒有定義則不顯示邊框

android:strokeWidth 定義路徑邊框的粗細尺寸

android:strokeAlpha 定義路徑邊框的透明度

android:fillAlpha 定義填充路徑顏色的透明度

android:trimPathStart 從路徑起始位置截斷路徑的比率,取值範圍從 0 到1

android:trimPathEnd 從路徑結束位置截斷路徑的比率,取值範圍從 0 到1

android:trimPathOffset 設置路徑截取的範圍,取值範圍從 0 到1

android:strokeLineCap 設置路徑線帽的形狀,取值爲 butt, round, square.

android:strokeLineJoin 設置路徑交界處的連接方式,取值爲 miter,round,bevel.

android:strokeMiterLimit 設置斜角的上限

group的可選項釋義

group :主要是用來設置路徑做動畫的關鍵屬性的

android:name 定義 group 的名字

android:rotation 定義該 group 的路徑旋轉多少度

android:pivotX 定義縮放和旋轉該 group 時候的 X 參考點。該值相對於 vector 的 viewport 值來指定的。

android:pivotY 定義縮放和旋轉該 group 時候的 Y 參考點。該值相對於 vector 的 viewport 值來指定的。

android:scaleX 定義 X 軸的縮放倍數

android:scaleY 定義 Y 軸的縮放倍數

android:translateX 定義移動 X 軸的位移。相對於 vector 的 viewport 值來指定的。

android:translateY 定義移動 Y 軸的位移。相對於 vector 的 viewport 值來指定的。

clip-path釋義

clip-path定義當前繪製的剪切路徑。clip-path只對當前的group和子group有效。

android:name 定義clip path的名字

android:pathData 和 path中的 android:pathData 的取值一樣。

vector可選項釋義

android:name 定義該drawable的名字

android:width 定義該 drawable 的內部(intrinsic)寬度,支持所有 Android 系統支持的尺寸,通常使用 dp

android:height 定義該 drawable 的內部(intrinsic)高度,支持所有 Android 系統支持的尺寸,通常使用 dp

android:viewportWidth 定義矢量圖視圖的寬度,視圖就是矢量圖 path 路徑數據所繪製的虛擬畫布

android:viewportHeight 定義矢量圖視圖的高度,視圖就是矢量圖 path 路徑數據所繪製的虛擬畫布

android:tint 定義該 drawable 的 tint 顏色。默認是沒有 tint 顏色的

android:tintMode 定義 tint 顏色的 Porter-Duff blending 模式,默認值爲 src_in

android:autoMirrored 設置當系統爲 RTL (right-to-left)
佈局的時候,是否自動鏡像該圖片。比如 阿拉伯語

android:alpha 該圖片的透明度屬性

5、Vector Drawables的兼容問題

爲了兼容api21以下版本,系統提供了2個支持庫support-vector-drawable及animated-vector-drawable,其中分別包含了VectorDrawableCompat和AnimatedVectorDrawableCompat。其中VectorDrawableCompat可以兼容到api 7,AnimatedVectorDrawableCompat可以兼容到api11。

通過如下配置來使用vectorDrawable支持庫

//For Gradle Plugin 2.0+
 android {
   defaultConfig {
     vectorDrawables.useSupportLibrary = true
    }
 }
(低於1.5或者更低版本的gradle配置方法見官網)

在加載drawable時,不是所有接受drawable id的地方都可以使用vector drawable的。當在使用矢量圖像時用app:srcCompat替換android:src,在代碼中可以使用 setImageResource() 來設置圖片源。
爲了更好的渲染,建議在定義矢量圖片時設置爲黑色,然後利用android:tint着色。

6、版本問題

com.android.support:appcompat-v7包25.4.0及以上版本的支持庫纔有以下特性:
1.path漸變 從一個path漸變到另外一個path。(即使使用了在api21以下的手機上無效,只是不報錯而已)
2.path變化的插值器
com.android.support:appcompat-v7包26.0.0-beta1及更高的支持庫有以下特性:
1.沿着path移動任意對象。(這一點不是很理解)
注意,在不支持的版本上應用以上特性可能會造成crash。

7、參考:

  1. https://developer.android.com/guide/topics/graphics/vector-drawable-resources.html
  2. https://developer.android.com/studio/write/vector-asset-studio.html#importing
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章