天天看点

《疯狂Android讲义》 -- Android 动画系列之自定义补间动画(三维动画) 前言 使用参考资料

前言

         Android提供了Animation作为补间动画抽象基类,并且为该抽象基类提供了AlphaAnimation、RotateAnimation、TranslateAnimation、ScaleAnimation四个实现类,这四个实现类只是补间动画的四种基本形式:透明度改变、旋转、位移、缩放。在实际项目中可能还需要一些更复杂的动画,比如让图片在“三维”空间内进行旋转动画等,这就需要开发者自己开发补间动画了。

         自定义补间动画并不难,需要继承Animation,继承Animation时关键是要重写该抽象基类的applyTransformation(float interpolatedTime, Transformation t)方法,该方法中两个参数说明如下:

  • interpolatedTime:代表了动画的时间进行比。不管动画实际的持续时间如何,当动画播放时,该参数总是自动从0变化到1。
  • Transformation:代表了补间动画在不同时刻对图形或组件的变形程度。

         从上面的介绍可以看出,实现自定义动画的关键就在于重写applyTransformation()方法时,根据interpolatedTime时间来动态地计算动画对图片或视图的变形程度。

         Transformaction代表了对图片或视图的变形程度,该对象里封装了一个Matrix对象,对它所包装的Matrix进行位移、倾斜、旋转等变换时,Transformaction将会控制对应的图片或视图进行相应的变换。

使用

         为了控制图片或视图进行三维空间的变换,还需要借助于Android提供的一个Camera,这个Camera并非代表手机的摄像头,而是一个空间变换工具,作用有点类似于Matrix,但功能更强大。

         Camera提供了如下常用的方法。

  • getMatrix(Matrix matrix):将Camera所做的变换应用到指定matrix上。
  • rotateX(float deg):使目标组件沿X轴旋转。
  • rotateY(float deg):使目标组件沿Y轴旋转。
  • rotateZ(float deg):使目标组件沿Z轴旋转。
  • translate(float x, float y, float z):使目标组件在三维空间里进行位移变换。
  • applyToCanvas(Canvas canvas):把Camera所做的变换应用到Camera上。

下面的程序将会利用Camera来自定义在三维空间的动画,该程序的自定义动画类代码如下:  

package com.yzx.myapplication;                  import android.graphics.Camera;              import android.graphics.Matrix;              import android.view.animation.Animation;              import android.view.animation.LinearInterpolator;              import android.view.animation.Transformation;                  /**              * Created by gv52jy1 on 2016/11/16.              */              public class MyAnimation extends Animation {              private float centerX;              private float centerY;              private int duration;              private Camera camera = new Camera();                  public MyAnimation(float x, float y, int duration) {              this.centerX = x;              this.centerY = y;              this.duration = duration;              }                  @Override              public void initialize(int width, int height, int parentWidth, int parentHeight) {              super.initialize(width, height, parentWidth, parentHeight);              // 设置动画的持续时间              setDuration(duration);              // 设置动画结束后效果保留              setFillAfter(true);              // 设置匀速变换              setInterpolator(new LinearInterpolator());              }                  /**              * @param interpolatedTime  代表抽象的动画持续时间,不管动画实际持续时间多长,              *                          interpolatedTime参数总是从0(动画开始时)变化到1(动画结束时)              * @param t 代表了对目标组件所做的改变              */              @Override              protected void applyTransformation(float interpolatedTime, Transformation t) {              super.applyTransformation(interpolatedTime, t);              camera.save();              // 根据interpolatedTime时间来控制x、y、z轴上的偏移              camera.translate(100.0f - 100.0f*interpolatedTime, 150.0f*interpolatedTime - 150, 80.0f - 80.0f*interpolatedTime);              // 设置根据interpolatedTime时间在x轴上旋转不同角度              camera.rotateX(360 * interpolatedTime);              // 设置根据interpolatedTime时间在y轴上旋转不同角度              camera.rotateY(360 * interpolatedTime);              // 获取Transformation参数的Matrix对象              Matrix matrix = t.getMatrix();              // 将Camera所做的变换应用到Transformation的Matrix上              camera.getMatrix(matrix);              matrix.preTranslate(-centerX,-centerY);              matrix.postTranslate(centerX,centerY);              camera.restore();                  }              }           

      在Java代码中启动动画

DisplayMetrics metrics = new DisplayMetrics();              getWindowManager().getDefaultDisplay().getMetrics(metrics);              textView.startAnimation(new MyAnimation(metrics.xdpi / 2, metrics.ydpi / 2,3500));           

参考资料

  • 《疯狂Android讲义》书籍
  •  http://blog.csdn.net/Airsaid/article/details/51591282