上篇文章中,我們探討了如何將svg圖片轉換成VectorDrawable,以在適應不同分辨率的同時減少資源文件的個數,同時也更易於維護。但是這並不是VectorDrawable的唯一好處-還可以用來製作動畫。這篇文章就是關於如何用VectorDrawable來實現android機器人聳肩的效果!
我們將要實現的動畫很簡單,在保持身體不動的同時,讓頭部和手臂在Y方向上上下移動。表面上看實現起來很複雜,因爲我們這裏只有一個Drawable(要是一般的Drawable估計的通過繪製來實現了)。但是有一個控件卻可以使事情變得非常簡單,那就是在Lollipop中和VectorDrawable一起被引入的AnimatedVectorDrawable。在上篇文章中,我們講到了path元素的name屬性是爲了描述path的用處,但它還可以用在爲指定path指定一個動畫。本例中我們需要動畫的path元素是頭部,左眼,右眼,左臂,右臂。問題是單個的<path>是沒有translateX和translateY屬性的,因此無法使用屬性動畫來控制<path>translateY,而<group>元素是有的,所以我們需要先將相關的<path>元素包裹在一個個的<group>元素中:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
|
<?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> |
現在再我們定義一個包含<animated-vector>的drawable文件,這個文件的作用是將動畫應用在指定的group中,使得某些部分的path動起來:
1
2
3
4
5
6
7
8
9
10
11
12
|
<?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> |
雖然我知道完全可以將頭、眼、和手臂放在一個group中,但是爲了演示一個<animated-vector>是如何控制多個group的動畫的,我有意把他們分成兩部分,實際運用中,不同的group目標動畫肯定是不一樣的。
<animated-vector>的最外層元素指定了我們要動畫的VectorDrawable資源-在本例中這個資源是android.xml,裏面的<target>元素根據group的name屬性指定group的動畫效果。
<vector>, <group>, <clip-path>, 和<path> 元素都有各自可以播放動畫的屬性,查閱VectorDrawable JavaDocs你會找到每種元素到底有那些屬性,以便針對這些屬性播放特定的動畫。比如:要使用tint效果需要作用於<vector>元素上,而修改填充顏色則需要作用於<path>元素。
聳肩的效果很簡單,只是個重複移動Y軸的animator:
1
2
3
4
5
6
7
8
9
10
11
|
<?xml version= "1.0" encoding= "utf-8" ?> <objectAnimator android:propertyName= "translateY" android:valueType= "floatType" android:valueFrom= "0" android:valueTo= "-10" android:repeatMode= "reverse" android:repeatCount= "infinite" android:duration= "250" /> </set> |
爲了運行這個動畫我們需要做幾件事情。首先,要將ImageView的src改爲動畫效果的drawable。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
|
<RelativeLayout xmlns:android= "http://schemas.android.com/apk/res/android" 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> |
如果運行現在的代碼,我們只能看到靜態的圖片。這是因爲我們需要手動調用播放動畫。我們將在Activity中去調用,如果Drawable是Animatable(AnimatedVectorDrawable實現了Animatable)的實例,將開始動畫。
1
2
3
4
5
6
7
8
9
10
11
12
13
|
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(); } } } |
運行代碼就會發現指定了animation的path出現動畫效果:
在接下來的文章中,我們將更深入的去了解AnimatedVectorDrawable,實現更酷的效果。
本篇文章的源代碼在這裏 here.
轉載請註明出處 http://jcodecraeer.com/a/anzhuokaifa/androidkaifa/2015/0301/2514.html