Android View动画——自定义View动画

If we don’t have the guts to try anything, what’s the meaning of life.
——如果我们任何事情都没有勇气去尝试,人生还有什么意义。

1. 自定义View动画

这里给出一个模仿QQ客户端的抖一抖特效:
https://images2015.cnblogs.com/blog/917478/201603/917478-20160319185142818-1993819298.gif
这里窗口抖动的特效代码为:

package com.wondertwo.qqTremble;

import android.view.animation.Animation;
import android.view.animation.Transformation;

/**
 * QQ抖一抖特效的自定义View动画实现
 * Created by wondertwo on 2016/3/17.
 */
public class QQTrembleAni extends Animation {
    @Override
    protected void applyTransformation(float interpolatedTime, Transformation t) {
        t.getMatrix().setTranslate(
                (float) Math.sin(interpolatedTime * 50) * 8,
                (float) Math.sin(interpolatedTime * 50) * 8
                );// 50越大频率越高,8越小振幅越小
        super.applyTransformation(interpolatedTime, t);
    }
}

首先,所有的自定义View动画都要继承android.view.animation.Animation 抽象类,重写initialize()applyTransformation() 这两个方法。

  • initialize() :对一些变量进行初始化
  • applyTransformation() : 通过矩阵修改动画数值,从而控制动画实现过程

applyTransformation(float interpolatedTime, Transformation t) 在动画执行过程中不断调用,interpolatedTime 表示当前动画进行的时间与动画总时间的比值。Transformation t 传递当前动画对象,一般可以通过代码 android.graphics.Matrix matrix = t.getMatrix() 获得 Matrix 矩阵对象,再设置 Matrix 对象,一般要用到 interpolatedTime 参数,以此达到控制动画实现的结果

以下为QQ抖一抖动画的测试类Activity,:


import android.app.Activity;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.RelativeLayout;

import com.wondertwo.R;

/**
 * 模仿QQ抖一抖效果的测试类
 * Created by wondertwo on 2016/3/17.
 */
public class QQTrembleTest extends Activity {

    private RelativeLayout rlTremble;
    private Button btnTremble;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_qq_tremble);
        rlTremble = (RelativeLayout) findViewById(R.id.rl_tremble);
        btnTremble = (Button) findViewById(R.id.btn_tremble);

        // 创建抖一抖动画对象
        final QQTrembleAni tremble = new QQTrembleAni();
        tremble.setDuration(800);// 持续时间800ms,持续时间越短频率越高
        tremble.setRepeatCount(2);// 重复次数,不包含第一次

        // 设置按钮点击监听
        btnTremble.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                // 启动抖一抖效果
                rlTremble.startAnimation(tremble);
            }
        });
    }
}

1.1 类似电视关机画面与图片3D旋转

在这里插入图片描述
电视关机代码:

import android.graphics.Matrix;
import android.view.animation.Animation;
import android.view.animation.Transformation;

/**
 * 通过矩阵变换模拟电视关闭效果,使图片的纵向比例不断缩小
 * Created by wondertwo on 2016/3/13.
 */
public class TVCloseAni extends Animation {

    private int mCenterWidth, mCenterHeight;

    @Override
    public void initialize(int width, int height, int parentWidth, int parentHeight) {
        super.initialize(width, height, parentWidth, parentHeight);
        // 设置默认时长
        setDuration(4000);
        // 保持动画的结束状态
        setFillAfter(true);
        // 设置默认插值器
        // setInterpolator(new BounceInterpolator());// 回弹效果的插值器
        mCenterWidth = width / 2;
        mCenterHeight = height /2;
    }

    @Override
    protected void applyTransformation(float interpolatedTime, Transformation t) {
        super.applyTransformation(interpolatedTime, t);
        final Matrix matrix = t.getMatrix();
        matrix.preScale(1,
                        1 - interpolatedTime,
                        mCenterWidth,
                        mCenterHeight);
    }
}

3D选择动画代码:

import android.graphics.Camera;
import android.graphics.Matrix;
import android.view.animation.Animation;
import android.view.animation.BounceInterpolator;
import android.view.animation.Transformation;

/**
 *
 * Created by wondertwo on 2016/3/13.
 */
public class CustomAni extends Animation {

    private int mCenterWidth, mCenterHeight;
    private Camera mCamera = new Camera();
    private float mRotateY = 0.0f;

    // 一般在此方法初始化一些动画相关的变量和值
    @Override
    public void initialize(int width, int height, int parentWidth, int parentHeight) {
        super.initialize(width, height, parentWidth, parentHeight);
        // 设置默认时长
        setDuration(4000);
        // 保持动画的结束状态
        setFillAfter(true);
        // 设置默认插值器
        setInterpolator(new BounceInterpolator());// 回弹效果的插值器
        mCenterWidth = width / 2;
        mCenterHeight = height /2;
    }

    // 暴露接口设置旋转角度
    public void setRotateY(float rotateY) {
        mRotateY = rotateY;
    }

    // 自定义动画的核心,在动画的执行过程中会不断回调此方法,并且每次回调interpolatedTime值都在不断变化(0----1)
    @Override
    protected void applyTransformation(float interpolatedTime, Transformation t) {
        super.applyTransformation(interpolatedTime, t);
        final Matrix matrix = t.getMatrix();
        mCamera.save();
        // 使用Camera设置Y轴方向的旋转角度
        mCamera.rotateY(mRotateY * interpolatedTime);
        // 将旋转变化作用到matrix上
        mCamera.getMatrix(matrix);
        mCamera.restore();
        // 通过pre方法设置矩阵作用前的偏移量来改变旋转中心
        matrix.preTranslate(mCenterWidth, mCenterHeight);// 在旋转之前开始位移动画
        matrix.postTranslate(-mCenterWidth, -mCenterHeight);// 在旋转之后开始位移动画
    }
}

猜你喜欢

转载自blog.csdn.net/weixin_43499030/article/details/89249238