【Android動畫】之Tween動畫 (漸變、縮放、位移、旋轉)

weixin_33831673發表於2014-10-10

Android 平臺提供了兩類動畫。 一類是Tween動畫,就是對場景裡的物件不斷的進行影像變化來產生動畫效果(旋轉、平移、放縮和漸變)。

第二類就是 Frame動畫,即順序的播放事先做好的影像,與gif圖片原理相似。

 

以下就講一下Tweene Animations。

 

主要類:

 

Animation   動畫

AlphaAnimation 漸變透明度

RotateAnimation 畫面旋轉

ScaleAnimation 漸變尺寸縮放

TranslateAnimation 位置移動

AnimationSet  動畫集

 

 

有了這些類,那麼我們怎樣來實現動畫效果呢? 

 

以自己定義View為例,該View非常easy,畫面上僅僅有一個圖片。 如今我們要對整個View分別實現各種Tween動畫效果。

 

AlphaAnimation

 

通過程式碼實現 AlphaAnimation,例如以下:

//初始化 Animation alphaAnimation = new AlphaAnimation(0.1f, 1.0f); //設定動畫時間 alphaAnimation.setDuration(3000); this.startAnimation(alphaAnimation); 

當中AlphaAnimation類第一個引數fromAlpha表示動畫起始時的透明度, 第二個引數toAlpha表示動畫結束時的透明度。 

setDuration用來設定動畫持續時間。

 

RotateAnimation


程式碼:

Animation rotateAnimation = new RotateAnimation(0f, 360f); rotateAnimation.setDuration(1000); this.startAnimation(rotateAnimation); 

當中RotateAnimation類第一個引數fromDegrees表示動畫起始時的角度, 第二個引數toDegrees表示動畫結束時的角度。 

另外還能夠設定伸縮模式pivotXType、pivotYType, 伸縮動畫相對於x,y 座標的開始位置pivotXValue、pivotYValue等。

 

ScaleAnimation

程式碼:

//初始化 Animation scaleAnimation = new ScaleAnimation(0.1f, 1.0f,0.1f,1.0f); //設定動畫時間 scaleAnimation.setDuration(500); this.startAnimation(scaleAnimation); 

ScaleAnimation類中

第一個引數fromX ,第二個引數toX:各自是動畫起始、結束時X座標上的伸縮尺寸。

第三個引數fromY ,第四個引數toY:各自是動畫起始、結束時Y座標上的伸縮尺寸。

另外還能夠設定伸縮模式pivotXType、pivotYType, 伸縮動畫相對於x,y 座標的開始位置pivotXValue、pivotYValue等。

 

TranslateAnimation

程式碼:

//初始化 Animation translateAnimation = new TranslateAnimation(0.1f, 100.0f,0.1f,100.0f); //設定動畫時間 translateAnimation.setDuration(1000); this.startAnimation(translateAnimation); 

TranslateAnimation類

 

第一個引數fromXDelta ,第二個引數toXDelta:各自是動畫起始、結束時X座標。

第三個引數fromYDelta ,第四個引數toYDelta:各自是動畫起始、結束時Y座標。

 

引數具體說明:

表二

XML節點 功能說明
alpha 漸變透明度動畫效果
<alpha
android:fromAlpha=”0.1″
android:toAlpha=”1.0″
android:duration=”3000″ />
fromAlpha

屬性為動畫起始時透明度

0.0表示全然透明
1.0表示全然不透明
以上值取0.0-1.0之間的float資料型別的數字
toAlpha 屬性為動畫結束時透明度

表三

scale 漸變尺寸伸縮動畫效果
<scale
android:interpolator= “@android:anim/accelerate_decelerate_interpolator”
android:fromXScale=”0.0″
android:toXScale=”1.4″
android:fromYScale=”0.0″
android:toYScale=”1.4″
android:pivotX=”50%”
android:pivotY=”50%”
android:fillAfter=”false”
android:startOffset=“700”
android:duration=”700″
android:repeatCount=”10″ />
fromXScale[float] fromYScale[float] 為動畫起始時,X、Y座標上的伸縮尺寸 0.0表示收縮到沒有
1.0表示正常無伸縮
值小於1.0表示收縮
值大於1.0表示放大
toXScale [float]
toYScale[float]
為動畫結束時,X、Y座標上的伸縮尺寸
pivotX[float]
pivotY[float]
為動畫相對於物件的X、Y座標的開始位置 屬性值說明:從0%-100%中取值,50%為物件的X或Y方向座標上的中點位置
       

表四

translate 畫面轉換位置移動動畫效果
<translate
android:fromXDelta=”30″
android:toXDelta=”-80″
android:fromYDelta=”30″
android:toYDelta=”300″
android:duration=”2000″ />
fromXDelta
toXDelta
為動畫、結束起始時 X座標上的位置  
fromYDelta
toYDelta
為動畫、結束起始時 Y座標上的位置  
       

表五

rotate 畫面轉移旋轉動畫效果
<rotate
android:interpolator=”@android:anim/accelerate_decelerate_interpolator”
android:fromDegrees=”0″
android:toDegrees=”+350″
android:pivotX=”50%”
android:pivotY=”50%”
android:duration=”3000″ />
fromDegrees 為動畫起始時物件的角度 說明
當角度為負數——表示逆時針旋轉
當角度為正數——表示順時針旋轉
(負數from——to正數:順時針旋轉)
(負數from——to負數:逆時針旋轉)
(正數from——to正數:順時針旋轉)
(正數from——to負數:逆時針旋轉)
toDegrees 屬性為動畫結束時物件旋轉的角度 能夠大於360度
pivotX
pivotY
為動畫相對於物件的X、Y座標的開始位 說明:以上兩個屬性值 從0%-100%中取值
50%為物件的X或Y方向座標上的中點位置
       

 

以上都是單獨的使用某個動畫,那麼怎樣讓多個動畫同一時候生效呢?


答案是 AnimationSet。  

初看整個類名,還以為僅僅是用來存放 Animation的一個Set, 細看才發現,該類也是繼承自 Animation的。

 

以下我們實現一個動畫,該動畫會讓圖片移動的同一時候,圖片透明度漸變,直接看程式碼吧。

//初始化 Translate動畫 translateAnimation = new TranslateAnimation(0.1f, 100.0f,0.1f,100.0f); //初始化 Alpha動畫 alphaAnimation = new AlphaAnimation(0.1f, 1.0f); //動畫集 AnimationSet set = new AnimationSet(true); set.addAnimation(translateAnimation); set.addAnimation(alphaAnimation); //設定動畫時間 (作用到每一個動畫) set.setDuration(1000); this.startAnimation(set); 

 

是不是認為非常easy呢?

 

 

附上整個View類的程式碼吧。

package com.yfz.view; import com.yfz.R; import android.content.Context; import android.graphics.Canvas; import android.graphics.drawable.BitmapDrawable; import android.util.Log; import android.view.KeyEvent; import android.view.View; import android.view.animation.AlphaAnimation; import android.view.animation.Animation; import android.view.animation.AnimationSet; import android.view.animation.RotateAnimation; import android.view.animation.ScaleAnimation; import android.view.animation.TranslateAnimation; public class TweenAnim extends View { //Alpha動畫 - 漸變透明度 private Animation alphaAnimation = null; //Sacle動畫 - 漸變尺寸縮放 private Animation scaleAnimation = null; //Translate動畫 - 位置移動 private Animation translateAnimation = null; //Rotate動畫 - 畫面旋轉 private Animation rotateAnimation = null; public TweenAnim(Context context) { super(context); } @Override protected void onDraw(Canvas canvas) { super.onDraw(canvas); Log.e("Tween", "onDraw"); //載入一個圖片 canvas.drawBitmap(((BitmapDrawable)getResources().getDrawable(R.drawable.gallery_photo_5)).getBitmap(), 0, 0, null); } @Override public boolean onKeyDown(int keyCode, KeyEvent event) { Log.e("Tween", "onKeyDown"); return true; } @Override public boolean onKeyUp(int keyCode, KeyEvent event) { Log.e("Tween", "onKeyDown"); switch (keyCode) { case KeyEvent.KEYCODE_DPAD_UP: Log.e("Tween", "onKeyDown - KEYCODE_DPAD_UP"); alphaAnimation = new AlphaAnimation(0.1f, 1.0f); //設定動畫時間 alphaAnimation.setDuration(3000); this.startAnimation(alphaAnimation); break; case KeyEvent.KEYCODE_DPAD_DOWN: Log.e("Tween", "onKeyDown - KEYCODE_DPAD_DOWN"); rotateAnimation = new RotateAnimation(0f, 360f); rotateAnimation.setDuration(1000); this.startAnimation(rotateAnimation); break; case KeyEvent.KEYCODE_DPAD_LEFT: Log.e("Tween", "onKeyDown - KEYCODE_DPAD_LEFT"); //初始化 scaleAnimation = new ScaleAnimation(0.1f, 1.0f,0.1f,1.0f); //設定動畫時間 scaleAnimation.setDuration(500); this.startAnimation(scaleAnimation); break; case KeyEvent.KEYCODE_DPAD_RIGHT: Log.e("Tween", "onKeyDown - KEYCODE_DPAD_RIGHT"); //初始化 translateAnimation = new TranslateAnimation(0.1f, 100.0f,0.1f,100.0f); //設定動畫時間 translateAnimation.setDuration(1000); this.startAnimation(translateAnimation); break; case KeyEvent.KEYCODE_DPAD_CENTER: Log.e("Tween", "onKeyDown - KEYCODE_DPAD_CENTER"); //初始化 Translate動畫 translateAnimation = new TranslateAnimation(0.1f, 100.0f,0.1f,100.0f); //初始化 Alpha動畫 alphaAnimation = new AlphaAnimation(0.1f, 1.0f); //動畫集 AnimationSet set = new AnimationSet(true); set.addAnimation(translateAnimation); set.addAnimation(alphaAnimation); //設定動畫時間 (作用到每一個動畫) set.setDuration(1000); this.startAnimation(set); break; default: break; } return true; } }  

 

在Activity中呼叫該類時,須要注意一定setFocusable(true), 否則焦點在Activity上的話,onKeyUp方法是不會生效的。

呼叫該View的程式碼:

TweenAnim anim = new TweenAnim(Lesson_11.this); anim.setFocusable(true); setContentView(anim); 

 

 

 


 

上面通過Java程式碼,實現了4中不同的Tween動畫,事實上在Android中全然能夠通過 XML檔案來實現動畫。這樣的方式可能更加簡潔、清晰,也更利於重用。 

以下我們分別對這幾種動畫改用xml來實現。

 

首先是AlphaAnimation。

alpha_anim.xml:

<?xml version="1.0" encoding="utf-8"?> <set xmlns:android="http://schemas.android.com/apk/res/android"> <alpha android:fromAlpha="0.1" android:toAlpha="1.0" android:duration="2000" /> </set>  

 

不用解釋了吧。

 

RotateAnimation

rotate_anim.xml:

<?xml version="1.0" encoding="utf-8"?> <set xmlns:android="http://schemas.android.com/apk/res/android"> <rotate android:interpolator="@android:anim/accelerate_decelerate_interpolator" android:fromDegrees="0" android:toDegrees="360" android:pivotX="50%" android:pivotY="50%" android:duration="500" /> </set>  

 

 

ScaleAnimation

scale_anim.xml:

<?xml version="1.0" encoding="utf-8"?> <set xmlns:android="http://schemas.android.com/apk/res/android"> <scale android:interpolator="@android:anim/accelerate_decelerate_interpolator" android:fromXScale="0.0" android:toXScale="1.0" android:fromYScale="0.0" android:toYScale="1.0" android:pivotX="50%" android:pivotY="50%" android:fillAfter="false" android:duration="500" /> </set> 

 

TranslateAnimation

translate_anim.xml:

 

<?xml version="1.0" encoding="utf-8"?> <set xmlns:android="http://schemas.android.com/apk/res/android"> <translate android:fromXDelta="10" android:toXDelta="100" android:fromYDelta="10" android:toYDelta="100" /> </set>  

 

佈局檔案都已經寫完,那麼怎樣來使用這些檔案呢?

 

事實上也非常easy,此時須要用到AnimationUtils類。 通過該類中 loadAnimation 方法來載入這些佈局檔案。

如:

rotateAnimation = AnimationUtils.loadAnimation(this.getContext(), R.anim.rotate_anim); 

 

這次View類的程式碼例如以下:

package com.yfz.view; import com.yfz.R; import android.content.Context; import android.graphics.Canvas; import android.graphics.drawable.BitmapDrawable; import android.util.Log; import android.view.KeyEvent; import android.view.View; import android.view.animation.AlphaAnimation; import android.view.animation.Animation; import android.view.animation.AnimationSet; import android.view.animation.AnimationUtils; import android.view.animation.RotateAnimation; import android.view.animation.ScaleAnimation; import android.view.animation.TranslateAnimation; public class TweenAnim2 extends View { //Alpha動畫 - 漸變透明度 private Animation alphaAnimation = null; //Sacle動畫 - 漸變尺寸縮放 private Animation scaleAnimation = null; //Translate動畫 - 位置移動 private Animation translateAnimation = null; //Rotate動畫 - 畫面旋轉 private Animation rotateAnimation = null; public TweenAnim2(Context context) { super(context); } @Override protected void onDraw(Canvas canvas) { super.onDraw(canvas); Log.e("Tween", "onDraw"); //載入一個圖片 canvas.drawBitmap(((BitmapDrawable)getResources().getDrawable(R.drawable.gallery_photo_5)).getBitmap(), 0, 0, null); } @Override public boolean onKeyDown(int keyCode, KeyEvent event) { Log.e("Tween", "onKeyDown"); return true; } @Override public boolean onKeyUp(int keyCode, KeyEvent event) { Log.e("Tween", "onKeyDown"); switch (keyCode) { case KeyEvent.KEYCODE_DPAD_UP: Log.e("Tween", "onKeyDown - KEYCODE_DPAD_UP"); alphaAnimation = AnimationUtils.loadAnimation(this.getContext(), R.anim.alpha_anim); this.startAnimation(alphaAnimation); break; case KeyEvent.KEYCODE_DPAD_DOWN: Log.e("Tween", "onKeyDown - KEYCODE_DPAD_DOWN"); rotateAnimation = AnimationUtils.loadAnimation(this.getContext(), R.anim.rotate_anim); this.startAnimation(rotateAnimation); break; case KeyEvent.KEYCODE_DPAD_LEFT: Log.e("Tween", "onKeyDown - KEYCODE_DPAD_LEFT"); scaleAnimation = AnimationUtils.loadAnimation(this.getContext(), R.anim.scale_anim); this.startAnimation(scaleAnimation); break; case KeyEvent.KEYCODE_DPAD_RIGHT: Log.e("Tween", "onKeyDown - KEYCODE_DPAD_RIGHT"); translateAnimation = AnimationUtils.loadAnimation(this.getContext(), R.anim.translate_anim); this.startAnimation(translateAnimation); break; case KeyEvent.KEYCODE_DPAD_CENTER: Log.e("Tween", "onKeyDown - KEYCODE_DPAD_CENTER"); //初始化 Translate動畫 translateAnimation = AnimationUtils.loadAnimation(this.getContext(), R.anim.translate_anim); //初始化 Alpha動畫 alphaAnimation = AnimationUtils.loadAnimation(this.getContext(), R.anim.alpha_anim); //動畫集 AnimationSet set = new AnimationSet(true); set.addAnimation(translateAnimation); set.addAnimation(alphaAnimation); //設定動畫時間 (作用到每一個動畫) set.setDuration(1000); this.startAnimation(set); break; default: break; } return true; } }  

 

好了,本次就這麼多。

 

參考: http://www.moandroid.com/?p=790

相關文章