If we don’t have the guts to try anything, what’s the meaning of life.
——如果我们任何事情都没有勇气去尝试,人生还有什么意义。
这里给出一个模仿QQ客户端的抖一抖特效:
这里窗口抖动的特效代码为:
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);
}
});
}
}
电视关机代码:
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);// 在旋转之后开始位移动画
}
}