工作中遇到一个动画需求,于是从网上找了个例子,修改加注释理解了一下。
理解步骤如下:
1:继承Animation,复写 applyTransformation()方法
2:在applyTransformation 中实现自己的动画算法,这个方法有两个参数 p1: float 动画变化速率 p2: 动画应用 对象
3:在这个圆周运动动画中,首先确定圆周运动范围 0-360°。
4: 在动画的刷新变化中 计算x,y 的坐标,最终通过不停刷新来达到效果。
5:计算x,y时分0°,90°,180°,270°,360°。和区间 (0-90°,90-180°,180-270°,270-360°)
然后通过三角函数计算即可。
6:动画的应用:
/** * 播放 搜索红包动画 */ public void playSearchAnimation() { CircleAnimation animation = new CircleAnimation(50); animation.setDuration(1000); animation.setRepeatCount(1);//设置大一点儿表示无限大。 animation.setInterpolator(new LinearInterpolator());//不停顿 // animation.setRepeatMode(Animation.RESTART); // animation.setRepeatCount(Animation.INFINITE); animation.setAnimationListener(new Animation.AnimationListener() { @Override public void onAnimationStart(Animation animation) { } @Override public void onAnimationEnd(Animation animation) { onAnmationEnd(); } @Override public void onAnimationRepeat(Animation animation) { } }); loading.startAnimation(animation); }
7 效果:
下面是源码:---------------------------------------------------------------------
package com.hanya.financing.global.utils;
import android.view.animation.Animation;
import android.view.animation.Transformation;
/**
* 圆周运动动画效果
*/
public class CircleAnimation extends Animation {
private int radii;
public CircleAnimation(int radii) {
this.radii = radii;
}
/**
* @param interpolatedTime 取值范围 0-1
* @param t
*/
@Override
protected void applyTransformation(float interpolatedTime, Transformation t) {
//根据取值范围 确定圆周运动的角度范围。0-360
// float d = 360 * interpolatedTime ;//+ 180; //算法一
float d = 360 * interpolatedTime + 180; //算法二
DebugUtil.e("--->" + d);
if (d > 360) { //算法二
d = d - 360;
}
//根据取值范围 确定圆周运动的角度范围。0-360
int[] ps = getNewLocation((int) d, radii, 0, 0);//
t.getMatrix().setTranslate(ps[0], ps[1] - radii);
}
/**
* @param newAngle 当前临时角度
* @param r 半径
* @param width 控件的宽
* @param height 控件的高
* @return
*/
public int[] getNewLocation(int newAngle, int r, int width, int height) {
int newAngle1;
int newX = 0, newY = 0;
/**
* 0-90
*/
if (newAngle == 0) {
newX = width;
newY = height - r;
} else if (newAngle == 90) {
newX = width + r;
newY = height;
} else if (newAngle == 180) {
newX = width;
newY = height + r;
} else if (newAngle == 270) {
newX = width - r;
newY = height;
} else if (newAngle == 360) {
newX = width;
newY = height - r;
} else if (newAngle > 360) {
newX = width;
newY = height - r;
} else if (newAngle > 0 && newAngle < 90) {
// 0-90 baidu:就拿sin30°为列:Math.sin(30*Math.PI/180)
// 思路为PI相当于π,而此时的PI在角度值里相当于180°,
// 所以Math.PI/180得到的结果就是1°,然后再乘以30就得到相应的30°
newX = (int) (width + (r * Math.sin(newAngle * Math.PI / 180)));
newY = (int) (height - (r * Math.cos(newAngle * Math.PI / 180)));
} else if (newAngle > 90 && newAngle < 180) {// 90-180
newAngle1 = 180 - newAngle;
newX = (int) (width + (r * Math.sin(newAngle1 * Math.PI / 180)));
newY = (int) (height + (r * Math.cos(newAngle1 * Math.PI / 180)));
} else if (newAngle > 180 && newAngle < 270) {//180-270
newAngle1 = 270 - newAngle;
newX = (int) (width - (r * Math.cos(newAngle1 * Math.PI / 180)));
newY = (int) (height + (r * Math.sin(newAngle1 * Math.PI / 180)));
} else if (newAngle > 270 && newAngle < 360) {//270-360
newAngle1 = 360 - newAngle;
newX = (int) (width - (r * Math.sin(newAngle1 * Math.PI / 180)));
newY = (int) (height - (r * Math.cos(newAngle1 * Math.PI / 180)));
}
return new int[]{newX, newY};
}
}