二十七、自定义补间动画

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

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

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

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

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

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

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

getMatrix(Matrix matrix):将 Camera所做的变换应用到指定matrix上。
rotateX(float deg):将目标组件沿Ⅹ轴旋转。
rotateY(float deg):将目标组件沿Y轴旋转。
rotateZ(float deg):将目标组件沿Z轴旋转。
translate(float x, float y, float z):把目标组件在三维空间里进行位移变换。applyToCanvas(Canvas canvas):把 Camera所做的变换应用到 Canvas上。
从上面的方法可以看出,Camera的主要用于支持三维空间的变换,那么手机中三维空间的坐标系统是怎样的呢?图显示了手机屏幕上的三维坐标系统。

手机上的三维坐标

三维空间内沿Y轴旋转

public class MyAnimation extends Animation {

    private int centerX;
    private int centerY;
    //定义动画持续时间
    private int duration;
    private Camera camera = new Camera();
    public MyAnimation(int centerX, int centerY, int duration){
        this.centerX = centerX;
        this.centerY = centerY;
        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 代表了动画的时间进行比。不管动画实际的持续时间如何,
     *                         当动画播放时,该参数总是自动从0变化到1的。
     * @param t 该参数代表了补间动画在不同时刻对图形或组件的变形程度。
     */
    @Override
    protected void applyTransformation(float interpolatedTime, Transformation t) {
        camera.save();
        //实际中根据需求选择一个或多个方法组合实现效果,需要很强的空间感
        //根据interpolatedTime时间来控制X、Y、Z轴上的偏移
        camera.translate(100.0f - 100.0f * interpolatedTime,
                150.0f * interpolatedTime - 150,
                80.0f - 80.0f * interpolatedTime);
        //设置根据interpolatedTime时间在Y轴上旋转的不同角度
        camera.rotateY(360 * interpolatedTime);
        //设置根据interpolatedTime时间在X轴上旋转的不同角度
        camera.rotateX(360 * interpolatedTime);
        Matrix matrix = t.getMatrix();
        camera.getMatrix(matrix);
        matrix.preTranslate(-centerX, -centerY);
        matrix.postTranslate(centerX, centerY);
        camera.restore();
    }
}
ImageView imageView = findViewById(R.id.imageView);
WindowManager windowManager = (WindowManager) getSystemService(WINDOW_SERVICE);
Display display = windowManager.getDefaultDisplay();
int screenWidth = display.getWidth();
int screenHeight = display.getHeight();
imageView.setAnimation(new MyAnimation(screenWidth / 2,
                screenHeight / 2, 3500));

你可能感兴趣的:(二十七、自定义补间动画)