• 7.5 自定义动画" level="2">7.5 自定义动画

    7.5 自定义动画" class="reference-link">7.5 自定义动画

    创建自定义动画非常简单,只需要实现它的applyTransformation的逻辑就可以了,不过通常情况下,还需要覆盖父类的initialize方法来实现一些初始化工作。applyTransformation方法有如下所示的两个参数。

    1. applyTransformation(
    2. float interpolatedTime,
    3. Transformation t)

    第一个参数interpolatedTime就是前面讲的插值器的时间因子,这个因子是由动画当前完成的百分比和当前时间所对应的插值所计算得来的,取值范围为0到1.0。基本就对应图7.4所绘制的曲线图走势。

    第二个参数Transformation非常简单,它是矩阵的封装类,一般使用这个类来获得当前的矩阵对象,代码如下。

    1. final Matrix matrix = t.getMatrix();

    通过改变获得的matrix对象,可以将动画效果实现出来,而对于matrix的变换操作,基本可以实现任何效果的动画。

    1. @Override
    2. protected void applyTransformation(
    3. float interpolatedTime,
    4. Transformation t) {
    5. final Matrix matrix = t.getMatrix();
    6. //通过matrix的各种操作来实现动画
    7. matrix.XXXXXX;
    8. }

    通过模拟电视机关闭的效果来看看简单的矩阵变换是如何实现动画效果的。电视机关闭的效果非常简单,让一个图片纵向比例不断缩小即可,对应的矩阵处理方法如下。

    1. final Matrix matrix = t.getMatrix();
    2. matrix.preScale(1,
    3. 1 - interpolatedTime,
    4. mCenterWidth,
    5. mCenterHeight);

    其中mCenterWidth、mCenterHeight即为缩放的中心点,设置为图片中心即可。这样,通过一个简单的矩阵变换,就可以模拟电视机关闭的动画,效果如图7.5所示。

    7.5 自定义动画 - 图1 图7.5 电视关闭效果

    当然,你可以设置更精确的插值器,并将0到1.0的时间因子拆分成不同的过程,从而对不同的过程采用不同的动画效果,模拟更加真实的特效。

    接下来结合矩阵,并使用Camera类来实现一个自定义的3D动画效果。要注意的是,这里的Camera并不是指手机中的相机,而是android.graphics.Camera中的Camera类,它封装了openGL的3D动画,从而可以非常方便地创建3D动画效果。把Camera想象成一个真实的摄像机,当物体固定在某处时,只要移动摄像机就能拍摄到具有立体感的图像,因此通过它可以实现各种3D效果,Camera类的坐标系如图7.6所示。

    7.5 自定义动画 - 图2 图7.6 Camera坐标系

    下面继续分析代码的实现。首先,在初始化方法中对Camera和一些其他参数进行初始化,代码如下。

    1. @Override
    2. public void initialize(int width,
    3. int height,
    4. int parentWidth,
    5. int parentHeight) {
    6. super.initialize(width, height, parentWidth, parentHeight);
    7. //设置默认时长
    8. setDuration(2000);
    9. //动画结束后保留状态
    10. setFillAfter(true);
    11. //设置默认插值器
    12. setInterpolator(new BounceInterpolator());
    13. mCenterWidth = width / 2;
    14. mCenterHeight = height / 2;
    15. }

    接下来,自定义动画的核心——如何定义动画的进行过程,代码如下。

    1. @Override
    2. protected void applyTransformation(
    3. float interpolatedTime,
    4. Transformation t) {
    5. final Matrix matrix = t.getMatrix();
    6. mCamera.save();
    7. //使用Camera设置旋转的角度
    8. mCamera.rotateY(mRotateY * interpolatedTime);
    9. //将旋转变换作用到matrix上
    10. mCamera.getMatrix(matrix);
    11. mCamera.restore();
    12. //通过pre方法设置矩阵作用前的偏移量来改变旋转中心
    13. matrix.preTranslate(mCenterWidth, mCenterHeight);
    14. matrix.postTranslate(-mCenterWidth, -mCenterHeight);
    15. }

    通过上面的代码可以看到,使用Camera类实现动画效果非常简单,无非就是设置三个坐标轴的旋转角度,不过需要注意的是最后两行代码,通过这两行代码,可以改变旋转时的默认旋转中心。程序运行结果如图7.7所示。

    7.5 自定义动画 - 图3 图7.7 程序运行效果

    点击后开始动画,这样一个Button会在设置的时长内,使用相应的插值器来完成动画,效果如图7.8所示。

    7.5 自定义动画 - 图4 图7.8 点击后效果