可以分為兩種機制
補間動畫 (tweened animation) - 在 android.view.animation 這個 package 下
逐格動畫 (frame-by-frame animation) - 由 android.graphics.drawable.AnimationDrawable 處理
為什麼說基本呢? 因為上述這兩種機制從 API level 1 開始就存在了
下面把這兩種稍微做個整理介紹
逐格動畫
其實就像是 gif 檔
可以在 res/drawable/ 定義一個 xml 去做設定
使用的時候要記得呼叫 start<item android:drawable="@drawable/wheel0" android:duration="50" /> <item android:drawable="@drawable/wheel1" android:duration="50" /> <item android:drawable="@drawable/wheel2" android:duration="50" />
@Override public void onWindowFocusChanged(boolean hasFocus) { if(hasFocus){ AnimationDrawable frameAnimation = (AnimationDrawable) img.getBackground(); //已將 xml 設為ImageView 的 background frameAnimation.start(); } super.onWindowFocusChanged(hasFocus); }
補間動畫
下面列出一些相關類別的建構函數
他們都繼承自 android.view.animation.Animation
android.view.animation.AlphaAnimation.AlphaAnimation(float fromAlpha, float toAlpha) android.view.animation.ScaleAnimation.ScaleAnimation(float fromX, float toX, float fromY, float toY) android.view.animation.TranslateAnimation.TranslateAnimation(int fromXType, float fromXValue, int toXType, float toXValue, int fromYType, float fromYValue, int toYType, float toYValue) android.view.animation.RotateAnimation.RotateAnimation(float fromDegrees, float toDegrees, int pivotXType, float pivotXValue, int pivotYType, float pivotYValue) android.view.animation.AnimationSet.AnimationSet(boolean shareInterpolator)除了 AnimationSet 之外,上面四個被 new 出來以後記得都要呼叫 setDuration(long durationMillis)
不然動畫是看不出來的(瞬間完成)
另一點需要注意的是
在 TranslateAnimation 跟 RotateAnimation 這邊
需要傳入的 fromXType, toXType, fromYType, toYType 的部分
是使用 Animation 定義的常數
int android.view.animation.Animation.ABSOLUTE = 0 [0x0]
int android.view.animation.Animation.RELATIVE_TO_SELF = 1 [0x1]
int android.view.animation.Animation.RELATIVE_TO_PARENT = 2 [0x2]
這會關係到後面給的數值是以誰為基準
要稍為留意一下
AnimationSet 使用 void android.view.animation.AnimationSet.addAnimation(Animation a)
這個 method 把 Animation 的子物件實體加進來
到時候會一起播放
不論是 AnimationSet 或其他 Animation 的子物件
都可以在 res/anim/ 使用 xml 的方式進行設定,也便於重複使用
<alpha android:fromAlpha="1.0" android:toAlpha="0.0" android:duration="1000" /> <rotate android:toDegrees="180" android:duration="1000"/> <scale android:toXScale="2" android:toYScale="2" android:duration="1000"/> <translate android:fromXDelta="0" android:toXDelta="100%p" android:fromYDelta="0" android:toYDelta="100" android:duration="1000" />
播放動畫的部分也說明一下
//如果來源是 xml 那需要先取得 Animation 實體 //Animation android.view.animation.AnimationUtils.loadAnimation(Context context, int id) throws NotFoundException animation = mationUtils.loadAnimation(this, animationXmlID); view.startAnimation(animation); //用code生成的話直接這一行播放
最後來順便提一下 Window Animations
就是 Activity 轉換時的過場動畫
這也是屬於 View Animations 的機制內
轉場動畫的寫法是這樣
注意 overridePendingTransition 的呼叫要緊接在 startActivity 或 finish 的呼叫之後
@Override public void finish() { super.finish(); //void android.app.Activity.overridePendingTransition(int enterAnim, int exitAnim) overridePendingTransition(R.anim.slide_in_right, R.anim.slide_out_right); }
在 API level 16 之後新增了 android.app.ActivityOptions 類別
可以跟 startActivity(Intent, Bundle) 搭配使用
ActivityOptions 有三個 static method
可以設定轉場動畫的類型
透過呼叫這三個 static method 會得到一個 ActivityOptions 實體
static ActivityOptions makeCustomAnimation(Context context, int enterResId, int exitResId)
static ActivityOptions makeScaleUpAnimation(View source, int startX, int startY, int startWidth, int startHeight)
static ActivityOptions makeThumbnailScaleUpAnimation(View source, Bitmap thumbnail, int startX, int startY)
之後再呼叫 ActivityOptions 實體的 toBundle()
就可得到要傳入startActivity(Intent, Bundle) 的 Bundle 物件
範例如下:
// ActivityOptions.makeCustomAnimation Bundle bundle = ActivityOptions.makeCustomAnimation( this, R.anim.slide_in_left, R.anim.slide_out_left ).toBundle(); startActivity(intent, translateBundle);
//ActivityOptions.makeScaleUpAnimation Bundle scaleBundle = ActivityOptions.makeScaleUpAnimation( v, 0, 0, v.getWidth(), v.getHeight() ).toBundle(); startActivity(intent, scaleBundle);
//ActivityOptions.makeThumbnailScaleUpAnimation BitmapDrawable drawable = (BitmapDrawable) thumbnail.getDrawable(); Bitmap bm = drawable.getBitmap(); Bundle scaleBundle = ActivityOptions.makeThumbnailScaleUpAnimation(thumbnail, bm, 0, 0) .toBundle(); startActivity(intent, scaleBundle);至於退場動畫還是要使用 overridePendingTransition 的方式
下一篇來整理一下 Android 3.0 以後的 Property Animation
相關資料:
YouTube - DevBytes: View Animations
YouTube - DevBytes: Window Animations
developer.android.com - AnimationDrawable
developer.android.com - android.view.animation
developer.android.com - ActivityOptions
沒有留言:
張貼留言