在Animation类中重写方法applyTransformation方法,该方法有两个参数
接下来实现一个以自身中心缩小到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()复原。
实现这个效果的思路是在一个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就是最开始调到中心,动画完成了就调回来。