Android動畫機制與使用技巧(三)——動畫補充知識
Android佈局動畫
佈局動畫是指作用在ViewGroup上,給ViewGroup增加View時新增一個動畫過渡效果。
最簡單的佈局動畫是在ViewGroup的XML中,使用以下程式碼來開啟佈局動畫。
android:animateLayoutChanges="true"
通過以上程式碼設定,當ViewGroup新增View時,子View會呈現逐漸顯示的過渡效果,不過這個效果是Android預設的顯示的過渡效果,且無法使用自定義的動畫來替換這個效果。
另外,還可以通過使用LayoutAnimationController類來自定義一個子View的過渡效果,程式碼如下所示:
RelativeLayout rl = (RelativeLayout) findViewById(R.id .rl_content);
//設定過渡動畫
ScaleAnimation sa = new ScaleAnimation(0, 1, 0, 1);
sa.setDuration(2000);
//設定佈局動畫的顯示屬性
LayoutAnimationController lac = new LayoutAnimationController(sa, 0.5f);
lac.setOrder(LayoutAnimationController.ORDER_NORMAL);
//為ViewGroup設定佈局動畫
rl.setLayoutAnimation (lac);
LayoutAnimationController的第一個引數,是需要作用的動畫,而第二個引數,則是每個子View顯示的delay時間。當delay時間不為0時,可以設定子View顯示的順序,如下所示:
- LayoutAnimationController.ORDER_NORMAL——順序
- LayoutAnimationController.ORDER_RANDOM——隨機
- LayoutAnimationController.ORDER_REVERSE——反序
Interpolators(插值器)
插值器是動畫中一個非常重要的概念,通過插值器,可以定義動畫變換速率,這一點非常類似物理中的加速度,其作用主要是控制目標變數的變化值進行對應的變化。同樣一個動畫變換起始值,在不同的插值器作用下,每個單位時間內所達到的變化值也是不一樣的。例如一個位移動畫,如果使用線性插值器,那麼在持續時間內,單位時間所移動的距離都是一樣的;如果使用加速度插值器,那麼單位時間內所移動的距離先是越來越大後來是越來越小。總之它們的變換速率不一樣,但最後都是在相同的規定時間內完成。
自定義動畫
建立自定義動畫非常簡單,只需要實現它的applyTransformation方法的邏輯就可以了,不過通常情況下,還需要覆蓋父類的initialize方法來實現一些初始化工作。applyTransformation方法有如下兩個引數。
protected void applyTransformation(float interpolatedTime, Transformation t)
第一個引數interpolatedTime就是插值器的時間因子,這個因子是由動畫當前完成的百分比和當前時間所對應的插值所計算出來的,取值範圍為0到1.0。
第二個引數Transformation非常簡單,它是矩陣的封裝類,一般使用這個類來獲得當前的矩陣物件,程式碼如下:
Matrix matrix = t.getMatrix();
通過改變獲得的matrix物件,可以將動畫效果實現出來,而對於matrix的變換操作,基本可以實現任何效果的動畫。
模擬電視關閉的效果
電視關閉的效果非常簡單,就是讓一個圖片縱向比例不斷縮小即可,對應的矩陣處理方法如下:
/**
* Created by Administrator on 2016/6/2.
* 電視關閉效果的動畫
*/
public class TVAnimation extends Animation {
//縮放的中心點,設定為圖片的中心即可
private int mCenterWidth;
private int mCenterHeight;
@Override
public void initialize(int width, int height, int parentWidth, int parentHeight) {
super.initialize(width, height, parentWidth, parentHeight);
// 設定預設時長
setDuration(1000);
// 動畫結束後保留狀態
setFillAfter(true);
// 設定預設插值器
setInterpolator(new AccelerateInterpolator());
mCenterWidth = width / 2;
mCenterHeight = height / 2;
}
@Override
protected void applyTransformation(float interpolatedTime, Transformation t) {
Matrix matrix = t.getMatrix();
matrix.postScale(1, 1 - interpolatedTime, mCenterWidth, mCenterHeight);
}
}
當然,可以設定更精確的插值器,並將0到1.0的時間因子拆分為不同的過程,從而對不同的過程採用不同的動畫效果,模擬更加真實的特效。
實現自定義的3D動畫效果
結合矩陣,並使用Camera類來實現一個自定義的3D動畫效果。要注意的是,這裡的Camera並不是指手機中的相機,而是android.graphics.Camera中的Camera類,它封裝了openGL的3D動畫,從而可以方便地建立3D動畫效果。把Camera想象成一個真實的攝像機,當物體固定在某處時,只要移動攝像機就能拍攝到具有立體感的影象,因此通過它可以實現各種3D效果。
自定義動畫的核心程式碼如下:
@Override
protected void applyTransformation(float interpolatedTime, Transformation t) {
Matrix matrix = t.getMatrix();
mCamera.save();
// 使用Camera設定旋轉的角度
mCamera.rotateY(interpolatedTime * mRotateY);
// 將旋轉變換作用到matrix上
mCamera.getMatrix(matrix);
mCamera.restore();
// 通過pre方法設定矩陣作用前的偏移量來改變旋轉中心
matrix.preTranslate(mCenterWidth, mCenterHeight);
matrix.postTranslate(-mCenterWidth, -mCenterHeight);
}
使用Camera類實現動畫效果非常簡單,無非就是設定三個座標軸的旋轉角度,不過通過最後兩行程式碼可以改變旋轉時預設旋轉中心。
效果如如下: