自定义动画
在Animation类中重写方法applyTransformation方法,该方法有两个参数
- float interpolatedTime:取值范围为0-1,具体我也不清楚,和时间有关的参数,应该是表示时间过去了多久。
- Transformation t:从该参数中可以的到Matrix,通过修改这个Matrix配合interpolatedTime实现动画
接下来实现一个以自身中心缩小到0的demo
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
| 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(); matrix.setScale( 1 - interpolatedTime, 1 - interpolatedTime, mWidthCenter, mHeightCenter); } }
|
1 2 3
| MyAnimation animation = new MyAnimation(); animation.setDuration(3000); icLauncher.startAnimation(animation);
|
也可以通过Camera的使用达到3D的效果,接下来修改一下上述代码实现一个图片围绕Y轴旋转的效果
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28
| 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();
camera.save(); camera.rotateY(360 * interpolatedTime); camera.getMatrix(matrix); camera.restore();
}
|
代码不复杂,刚开始创建一个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,先贴代码
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54
|
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.preTranslate(-centerX, -centerY); matrix.postTranslate(centerX, centerY); } }
|
基本上面讲过,但有一些不同。我们通过设置camera的z轴距离实现远离和靠近的效果,当splash旋转的时候我们渐渐远离,这是reverse为false,主页出现时渐渐靠近,reverse为true。最后的matrix调整translate是调整matrix作用的中心,pre就是最开始调到中心,动画完成了就调回来。
