主要思路Tween 動畫經過對 View 的內容完成一系列的圖形變換 (包括平移、縮放、旋轉、改變透明度)來實現動畫效果。html 具體來說,預先定義一組指令,這些指令指定了圖形變換的類型、觸發時間、持續時間。這些指令能夠是以 XML 文件方式定義,也能夠是以源代碼方式定義。程序沿着時間線執行這些指令就能夠實現動畫效果。linux 動畫的進度使用 Interpolator 控制,android 提供了幾個 Interpolator 子類,實現了不一樣的速度曲線,如LinearInterpolator 實現了勻速效果、 Accelerateinterpolator 實現了加速效果、DecelerateInterpolator 實現了減速效果等。還能夠定義本身的 Interpolator 子類,實現拋物線、自由落體等物理效果。android 動畫的運行模式有兩種:編程
圖形變換經過仿射矩陣實現。圖形變換是圖形學中的基本知識。簡單來講就是,每種變換都是一次矩陣運算。在 Android 中,Canvas 類中包含當前矩陣,當調用 Canvas.drawBitmap (bmp, x, y, Paint) 繪製時,android 會先把 bmp 作一次矩陣運算,而後將運算的結果顯示在 Canvas 上。這樣,編程人員只需不斷修改 Canvas 的矩陣並刷新屏幕,View 裏的對象就會不停的作圖形變換,動畫就造成了。canvas 在 android 中提供了 Animation 、 Interpolator、Transformation 等類具體實現 Tween 動畫,下面逐一分析。app Animation 類及其子類Animation 類及其子類是動畫的核心模塊,它實現了各類動畫效果,如平移、縮放、旋轉、改變透明度等。函數 Tween 動畫的每一楨都根據 Interpolator 對 view 的內容作一次圖形變換,所以 Animation 的核心工做是作變換(transformation)。動畫 Aniamtion 是基類,他記錄了動畫的通用屬性和方法。主要的屬性包括動畫持續時間、重複次數、interpolator 等。動畫裏最重要的方法是 getTransformation (currentTime, outTransformation),該方法根據當前間 (currentTime) 和 interpolator,計算當前的變換,在 outTransformation 中返回。this TranslateAnimation、RotateAnimation、AlphaAnimation 等是 Animation 的子類,分別實現了平移、旋轉、改變 Alpha 值等動畫。線程 每一個動畫都重載了父類的 applyTransformation 方法,這個方法會被父類的 getTransformation 方法調用。另外每一個動畫還有個 initialize 方法,完成初始化工做。 不一樣的動畫具備不一樣的屬性,如 RotateAnimation 的屬性是起始角度、終止角度和旋轉點座標, TranslateAnimation 的屬性是起始位置和終止位置。AlphaAnimation 的屬性是起始 alpha 值和終止 alpha 值。 Animation 類及其子類的類圖以下所示:
Interpolator 類及其子類Interpolator 定義了動畫的變化速度,能夠實現勻速、正加速、負加速、無規則變加速等; Interpolator 是基類,封裝了全部 Interpolator 的共同方法,它只有一個方法,即 getInterpolation (float input),該方法 maps a point on the timeline to a multiplier to be applied to the transformations of an animation. LinearInerpolator、AccelerateInterpolator, DecelerateInterpolator, AccelerateDecelerateInterpolator,CycleInterpolator 是 Interpolator 的子類,分別實現了勻速、加速、減速、變速、循環等效果。 對於 LinearInterpolator ,變化率是個常數,即 f (x) = x. public float getInterpolation(float input) { return input; } 對於 AccelerateInterpolator,開始變化很慢,而後逐漸變快,即 f(x) = x*x 或者 f(x) = pow(x, 2*mFactor). public float getInterpolation(float input) { if (mFactor == 1.0f) { return (float)(input * input); } else { return (float)Math.pow(input, 2 * mFactor); } } 對於 AccelerateDecelerateInterpolator,變化率開始和結束都很慢,但中間很快,即 f(x) = (cos ((x+1)*PI) / 2.0f) + 0.5f. public float getInterpolation(float input) { return (float)(Math.cos((input + 1) * Math.PI) / 2.0f) + 0.5f; } Interpolator 類及其子類的類圖以下所示:
Transformation 類Transformation 記錄了仿射矩陣 Matrix,動畫每觸發一次,會對原來的矩陣作一次運算, View 的 Bitmap 與這個矩陣相乘就可實現相應的操做(旋轉、平移、縮放等)。 Transformation 類封裝了矩陣和 alpha 值,它有兩個重要的成員,一是 mMatrix,二是 mAlpha。 Transformation 類圖以下所示:
如何在 View 中實現動畫從邏輯上講,實現動畫須要以下幾步:
整個流程可用一個序列圖表示:
使用樣例下面的代碼是一個 view,系統建立 view 時會調用 onCreate 方法,該方法定義了一個 TranslateAniamtion,指定了移動起點和終點,動畫持續時間爲 1s,最後調用 startAnimation 將該動畫保存在 View 的成員 mCurrentAnianmtion 中並啓動動畫。 注意,在 View 中須要定義成員變量 mCurrentAnimation 和 mTransformation ,分別記錄當前的動畫和變換。另外須要定義成員函數 startAnimation 啓動動畫。 class MyView extends View { Animation mCurrentAnimation = null; Transformation mTransformation = new Transformation;
private void setAnimation(Animation animation) {
public void startAnimation(Animation animation) {
long curTime = SystemClock.uptimeMillis (); if (mCurrentAniamtion == null){ canvas.drawBitmap (b, x, y, mPaint); } else { if (!mCurrentAnimation.isInitialized()) //initialize animation mCurrentAnimation.initialize (w, h, pw, ph); boolean more = mCurrentAnimation.getTransformation (curTime, mTransformation); if(more) { Matrix m = canvas.getMatrix(); canvas.setMatrix (mTransformation.getMatrix()); canvas.drawBitmap (b, x, y, mPaint); canvas.setMatrix (m); this.invalidate (); } else { mCurrentAnimation = null; this.invalidate (); } }
}
Animation anim = new TranslateAnimation (10, 20, 0, 0); anim.setDuration (1000); // 1s anim.setInterpolator (new AcceleratInterpolator(3.0f)); startAniamtion (anim); } }
原文:http://www.linuxgraphics.cn/animation/android_tween_animation.html |