1. 程式人生 > >Android中的Drawable資源—— VectorDrawable

Android中的Drawable資源—— VectorDrawable

在android5.0(API Level 21)中使用向量圖:vector drawable,vector drawable的特點是它不會因為影象的縮放而失真。為了相容android 5.0以前的版本,Google推出了Android Support Library 23.2,下面我們來大致介紹一下。

一、VectorDrawable

與vector drawable資源對應的類是VectorDrawable。要建立一個vector drawable,你需要在xml的的元素下定義好vector drawable的形狀資料。

首先看個例子:檔案android.xml

<?xml version="1.0" encoding="utf-8"?>
<vector xmlns:android="http://schemas.android.com/apk/res/android" android:viewportWidth="500" android:viewportHeight="500" android:width="500px" android:height="500px"> <group android:name="android"> <group android:name="head_eyes"> <path android:name
="head" android:fillColor="#9FBF3B" android:pathData="M301.314,83.298l20.159-29.272c1.197-1.74,0.899-4.024-0.666-5.104c-1.563-1.074-3.805-0.543-4.993,1.199L294.863,80.53c-13.807-5.439-29.139-8.47-45.299-8.47c-16.16,0-31.496,3.028-45.302,8.47l-20.948-30.41c-1.201-1.74-3.439-2.273-5.003-1.199c-1.564,1.077-1.861,3.362-0.664,5.104l20.166,29.272c-32.063,14.916-54.548,43.26-57.413,76.34h218.316C355.861,126.557,333.375,98.214,301.314,83.298"
/>
<path android:name="left_eye" android:fillColor="#FFFFFF" android:pathData="M203.956,129.438c-6.673,0-12.08-5.407-12.08-12.079c0-6.671,5.404-12.08,12.08-12.08c6.668,0,12.073,5.407,12.073,12.08C216.03,124.03,210.624,129.438,203.956,129.438" /> <path android:name="right_eye" android:fillColor="#FFFFFF" android:pathData="M295.161,129.438c-6.668,0-12.074-5.407-12.074-12.079c0-6.673,5.406-12.08,12.074-12.08c6.675,0,12.079,5.409,12.079,12.08C307.24,124.03,301.834,129.438,295.161,129.438" /> </group> <group android:name="arms"> <path android:name="left_arm" android:fillColor="#9FBF3B" android:pathData="M126.383,297.598c0,13.45-10.904,24.354-24.355,24.354l0,0c-13.45,0-24.354-10.904-24.354-24.354V199.09c0-13.45,10.904-24.354,24.354-24.354l0,0c13.451,0,24.355,10.904,24.355,24.354V297.598z" /> <path android:name="right_arm" android:fillColor="#9FBF3B" android:pathData="M372.734,297.598c0,13.45,10.903,24.354,24.354,24.354l0,0c13.45,0,24.354-10.904,24.354-24.354V199.09c0-13.45-10.904-24.354-24.354-24.354l0,0c-13.451,0-24.354,10.904-24.354,24.354V297.598z" /> </group> <path android:name="body" android:fillColor="#9FBF3B" android:pathData="M140.396,175.489v177.915c0,10.566,8.566,19.133,19.135,19.133h22.633v54.744c0,13.451,10.903,24.354,24.354,24.354c13.451,0,24.355-10.903,24.355-24.354v-54.744h37.371v54.744c0,13.451,10.902,24.354,24.354,24.354s24.354-10.903,24.354-24.354v-54.744h22.633c10.569,0,19.137-8.562,19.137-19.133V175.489H140.396z" /> </group> </vector>

我們可以就像一般drawable一樣去使用上面定義的VectorDrawable。

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:paddingLeft="@dimen/activity_horizontal_margin"
    android:paddingRight="@dimen/activity_horizontal_margin"
    android:paddingTop="@dimen/activity_vertical_margin"
    android:paddingBottom="@dimen/activity_vertical_margin"
    tools:context=".VectorDrawablesActivity">

    <ImageView
        android:id="@+id/android"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:src="@drawable/android"
        android:contentDescription="@null" />

</RelativeLayout>

這裡寫圖片描述

根元素 vector 是用來定義這個向量圖的,該元素包含如下屬性:

android:name 定義該drawable的名字
android:width 定義該 drawable 的內部(intrinsic)寬度,支援所有 Android 系統支援的尺寸,通常使用 dp
android:height 定義該 drawable 的內部(intrinsic)高度,支援所有 Android 系統支援的尺寸,通常使用 dp
android:viewportWidth 定義向量圖檢視的寬度,檢視就是向量圖 path 路徑資料所繪製的虛擬畫布
android:viewportHeight 定義向量圖檢視的高度,檢視就是向量圖 path 路徑資料所繪製的虛擬畫布
android:tint 定義該 drawabletint 顏色。預設是沒有 tint 顏色的
android:tintMode 定義 tint 顏色的 Porter-Duff blending 模式,預設值為 src_in
android:autoMirrored 設定當系統為 RTL (right-to-left) 佈局的時候,是否自動映象該圖片。比如 阿拉伯語。
android:alpha 該圖片的透明度屬性

有時候我們需要對幾個路徑一起處理,這樣就可以使用 group 元素來把多個 path 放到一起。 group 支援的屬性如下:

android:name 定義 group 的名字
android:rotation 定義該 group 的路徑旋轉多少度
android:pivotX 定義縮放和旋轉該 group 時候的 X 參考點。該值相對於 vectorviewport 值來指定的。
android:pivotY 定義縮放和旋轉該 group 時候的 Y 參考點。該值相對於 vectorviewport 值來指定的。
android:scaleX 定義 X 軸的縮放倍數
android:scaleY 定義 Y 軸的縮放倍數
android:translateX 定義移動 X 軸的位移。相對於 vectorviewport 值來指定的。
android:translateY 定義移動 Y 軸的位移。相對於 vectorviewport 值來指定的。

通過上面的屬性可以看出, group 主要是用來設定路徑做動畫的關鍵屬性的。

path 元素裡面的 pathData 就是向量圖的路徑資料,除此之外還可以設定其他屬性。 path 元素一共包含如下屬性:

android:name 定義該 path 的名字,這樣在其他地方可以通過名字來引用這個路徑
android:pathData 和 SVG 中 d 元素一樣的路徑資訊。
android:fillColor 定義填充路徑的顏色,如果沒有定義則不填充路徑
android:strokeColor 定義如何繪製路徑邊框,如果沒有定義則不顯示邊框
android:strokeWidth 定義路徑邊框的粗細尺寸
android:strokeAlpha 定義路徑邊框的透明度
android:fillAlpha 定義填充路徑顏色的透明度
android:trimPathStart 從路徑起始位置截斷路徑的比率,取值範圍從 01
android:trimPathEnd 從路徑結束位置截斷路徑的比率,取值範圍從 01
android:trimPathOffset 設定路徑擷取的範圍 Shift trim region (allows showed region to include the start and end), in the range from 0 to 1.
android:strokeLineCap 設定路徑線帽的形狀,取值為 butt, round, square.
android:strokeLineJoin 設定路徑交界處的連線方式,取值為 miter,round,bevel.
android:strokeMiterLimit 設定斜角的上限,Sets the Miter limit for a stroked path.

注:當strokeLineJoin設定為 “miter” 的時候, 繪製兩條線段以銳角相交的時候,所得的斜面可能相當長。當斜面太長,就會變得不協調。strokeMiterLimit 屬性為斜面的長度設定一個上限。這個屬性表示斜面長度和線條長度的比值。預設是 10,意味著一個斜面的長度不應該超過線條寬度的 10 倍。如果斜面達到這個長度,它就變成斜角了。當 strokeLineJoin 為 “round” 或 “bevel” 的時候,這個屬性無效。

vector 還支援 clip-path 元素。定義當前繪製的剪下路徑。注意,clip-path 只對當前的 group 和子 group 有效。另外這個clip-path只是在API大於等於21以上使用。

android:name 定義 clip path 的名字
android:pathDataandroid:pathData 的取值一樣。

二、AnimatedVectorDrawable

AnimatedVectorDrawable可以讓VectorDrawable動起來。AnimatedVectorDrawable通過改變VectorDrawable的屬性來讓VectorDrawable呈現動畫效果。

通常定義一個AnimatedVectorDrawable需要以下三個xml檔案:

1.vector drawable本身:res/drawable/中定義一個有<vector>元素的xml檔案,參考上面對VectorDrawable的定義。

2.vector drawable的動畫檔案(Animated vector drawable):res/drawable/中定義一個有<animated-vector>元素的xml檔案。

3.一個或者多個屬性動畫檔案:res/drawable/中定義一個有<objectAnimator>元素的xml檔案。

例如,針對上面的vector,我們定義一個動畫animated_android.xml。

<?xml version="1.0" encoding="utf-8"?>
<animated-vector xmlns:android="http://schemas.android.com/apk/res/android"
    android:drawable="@drawable/android">

    <target
        android:animation="@animator/shrug"
        android:name="head_eyes" />

    <target
        android:animation="@animator/shrug"
        android:name="arms" />
</animated-vector>

<?xml version="1.0" encoding="utf-8"?>

shrug.xml動畫檔案如下:

<set xmlns:android="http://schemas.android.com/apk/res/android">
    <objectAnimator
        android:propertyName="translateY"
        android:valueType="floatType"
        android:valueFrom="0"
        android:valueTo="-10"
        android:repeatMode="reverse"
        android:repeatCount="infinite"
        android:duration="250" />
</set>

下面是我們的佈局檔案:

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:paddingLeft="@dimen/activity_horizontal_margin"
    android:paddingRight="@dimen/activity_horizontal_margin"
    android:paddingTop="@dimen/activity_vertical_margin"
    android:paddingBottom="@dimen/activity_vertical_margin"
    tools:context=".VectorDrawablesActivity">

    <ImageView
        android:id="@+id/android"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:src="@drawable/animated_android"
        android:contentDescription="@null" />

</RelativeLayout>

下面是程式碼:

public class VectorDrawablesActivity extends Activity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_vector_drawables);
        ImageView androidImageView = (ImageView) findViewById(R.id.android);
        Drawable drawable = androidImageView.getDrawable();
        if (drawable instanceof Animatable) {
            ((Animatable) drawable).start();
        }
    }
}

這裡寫圖片描述

歡迎關注微信公眾號:DroidMind
精品內容獨家釋出平臺


呈現與部落格不一樣的技術乾貨