自定義動畫
在Animation類中重寫方法applyTransformation方法,該方法有兩個參數
- float interpolatedTime:取值範圍爲0-1,具體我也不清楚,和時間有關的參數,應該是表示時間過去了多久。
- Transformation t:從該參數中可以的到Matrix,通過修改這個Matrix配合interpolatedTime實現動畫
接下來實現一個以自身中心縮小到0的demo
public class MyAnimation extends Animation {
private int mWidthCenter, mHeightCenter;
//重寫初始化方法,可以得到當前目標的長寬
@Override
public void initialize(int width, int height, int parentWidth, int parentHeight) {
super.initialize(width, height, parentWidth, parentHeight);
this.mWidthCenter = width / 2;
this.mHeightCenter = height / 2;
setFillAfter(true);
}
@Override
protected void applyTransformation(float interpolatedTime, Transformation t) {
Matrix matrix = t.getMatrix();
//1-interpolatedTime從1到0完成動畫
matrix.setScale(
1 - interpolatedTime, 1 - interpolatedTime,
mWidthCenter, mHeightCenter);
}
}
MyAnimation animation = new MyAnimation();
animation.setDuration(3000);
icLauncher.startAnimation(animation);
也可以通過Camera的使用達到3D的效果,接下來修改一下上述代碼實現一個圖片圍繞Y軸旋轉的效果
//創建一個Camera
Camera camera = new Camera();
@Override
public void initialize(int width, int height, int parentWidth, int parentHeight) {
super.initialize(width, height, parentWidth, parentHeight);
this.mWidthCenter = width / 2;
this.mHeightCenter = height / 2;
setFillAfter(true);
}
@Override
protected void applyTransformation(float interpolatedTime, Transformation t) {
Matrix matrix = t.getMatrix();
/*
matrix.setScale(
1 - interpolatedTime, 1 - interpolatedTime,
mWidthCenter, mHeightCenter);
*/
camera.save();
camera.rotateY(360 * interpolatedTime);
camera.getMatrix(matrix);
camera.restore();
//matrix.preTranslate(mWidthCenter, mHeightCenter);
//matrix.postTranslate(-mWidthCenter, -mHeightCenter);
}
代碼不復雜,剛開始創建一個Camera,然後在applyTransformation方法中對camera旋轉,xy座標就是普通的xy座標,向右x正方向,向下y正方向,camera其實可以看作是在z軸上從上向下看的,也就是我們平時的視角,現在讓camera繞y旋轉,這裏需要注意,我們通過360 * interpolatedTime完成0到360度的旋轉,但是每次都是從0開始旋轉,所以在旋轉之前需要save()保存camera最開始的位置(0的地方),完成旋轉後將參數通過getMatrix(matrix)傳遞給matrix,然後restore()復原。
splash切換效果
實現這個效果的思路是在一個FrameLayout中包含兩個RelativeLayout,一個是splash,一個是主頁面,剛開始主頁面是invisible的,然後旋轉FrameLayout到90度,這是已經看不見了,然後把splash設爲gone,主頁設爲visible,繼續從270轉到360。思路就是這樣,但是我們需要一個3d旋轉的類,我們就靠上面學習的自定義Animation,先貼代碼
/**
* 實現3d旋轉的核心類
*/
public class Rotate3d extends Animation {
private Camera mCamera;
private float fromDegrees;
private float toDegrees;
private int centerX;
private int centerY;
private boolean reverse;
public Rotate3d(float fromDegrees, float toDegrees, int centerX, int centerY, boolean reverse) {
this.fromDegrees = fromDegrees;
this.toDegrees = toDegrees;
this.centerX = centerX;
this.centerY = centerY;
this.reverse = reverse;
}
@Override
public void initialize(int width, int height, int parentWidth, int parentHeight) {
super.initialize(width, height, parentWidth, parentHeight);
mCamera = new Camera();
}
@Override
protected void applyTransformation(float interpolatedTime, Transformation t) {
super.applyTransformation(interpolatedTime, t);
Matrix matrix = t.getMatrix();
mCamera.save();
if (!reverse) {
// 距離越來越遠
mCamera.translate(0, 0, 550 * interpolatedTime);
} else {
// 距離越來越近
mCamera.translate(0, 0, 550 * (1 - interpolatedTime));
}
float degrees = fromDegrees + (toDegrees - fromDegrees) * interpolatedTime;
mCamera.rotateY(degrees);
mCamera.getMatrix(matrix);
mCamera.restore();
// 調整matrix作用的中心
matrix.preTranslate(-centerX, -centerY);
matrix.postTranslate(centerX, centerY);
}
}
基本上面講過,但有一些不同。我們通過設置camera的z軸距離實現遠離和靠近的效果,當splash旋轉的時候我們漸漸遠離,這是reverse爲false,主頁出現時漸漸靠近,reverse爲true。最後的matrix調整translate是調整matrix作用的中心,pre就是最開始調到中心,動畫完成了就調回來。