public class CustomEvaluator extends Activity {
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.animator_custom_evaluator);
LinearLayout container = (LinearLayout) findViewById(R.id.container);
final MyAnimationView animView = new MyAnimationView(this);
container.addView(animView);
Button starter = (Button) findViewById(R.id.startButton);
starter.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
animView.startAnimation();
}
});
}
public class XYHolder {
private float mX;
private float mY;
public XYHolder(float x, float y) {
mX = x;
mY = y;
}
public float getX() {
return mX;
}
public void setX(float x) {
mX = x;
}
public float getY() {
return mY;
}
public void setY(float y) {
mY = y;
}
}
public class XYEvaluator implements TypeEvaluator {
public Object evaluate(float fraction, Object startValue, Object endValue) { //你可以自己计算在某个时间点的位置
XYHolder startXY = (XYHolder) startValue; //这里做的是匀速直线运动
XYHolder endXY = (XYHolder) endValue;
return new XYHolder(startXY.getX() + fraction * (endXY.getX() - startXY.getX()),
startXY.getY() + fraction * (endXY.getY() - startXY.getY()));
}
}
public class BallXYHolder {
private ShapeHolder mBall;
public BallXYHolder(ShapeHolder ball) {
mBall = ball;
}
public void setXY(XYHolder xyHolder) {
mBall.setX(xyHolder.getX());
mBall.setY(xyHolder.getY());
}
public XYHolder getXY() {
return new XYHolder(mBall.getX(), mBall.getY());
}
}
public class MyAnimationView extends View implements ValueAnimator.AnimatorUpdateListener {
public final ArrayList<ShapeHolder> balls = new ArrayList<ShapeHolder>();
ValueAnimator bounceAnim = null;
ShapeHolder ball = null;
BallXYHolder ballHolder = null;
public MyAnimationView(Context context) {
super(context);
ball = createBall(25, 25);
ballHolder = new BallXYHolder(ball);
}
private void createAnimation() {
if (bounceAnim == null) {
XYHolder startXY = new XYHolder(30f, 100f);//动画开始点
XYHolder midXY = new XYHolder(300f, 700f); //中间点
XYHolder endXY = new XYHolder(400f, 500f);//结束点
// 在这里 xY对于的是 BallXYHolder 对象的getXY 和setXY ,这里有个地方需要注意get 和set 的第一个
//字母会被转化为大写 所以xY 和XY 都可以实现 动画 但是 xy 和Xy 对应的却是 getXy 和 setXy 故不
//能实现动画会报方法不能找到的错误.
//这里的执行顺序是这样的
//1. 读取startXY midXY endXY
//2. 通过XYEvaluator的 evaluate 计算当前帧 的 位置
//3. 读取 返回的XYHolder 通过 BallXYHolder 的setXY 来这是小球的位置
bounceAnim = ObjectAnimator.ofObject(ballHolder, "xY",
new XYEvaluator(), startXY, midXY ,endXY); //values参数可以随便设置几个设几个
bounceAnim.setDuration(1500);
bounceAnim.addUpdateListener(this);
}
}
public void startAnimation() {
createAnimation();
bounceAnim.start();
}
private ShapeHolder createBall(float x, float y) {
OvalShape circle = new OvalShape();
circle.resize(50f, 50f);
ShapeDrawable drawable = new ShapeDrawable(circle);
ShapeHolder shapeHolder = new ShapeHolder(drawable);
shapeHolder.setX(x - 25f);
shapeHolder.setY(y - 25f);
int red = (int)(Math.random() * 255);
int green = (int)(Math.random() * 255);
int blue = (int)(Math.random() * 255);
int color = 0xff000000 | red << 16 | green << 8 | blue;
Paint paint = drawable.getPaint(); //new Paint(Paint.ANTI_ALIAS_FLAG);
int darkColor = 0xff000000 | red/4 << 16 | green/4 << 8 | blue/4;
RadialGradient gradient = new RadialGradient(37.5f, 12.5f,
50f, color, darkColor, Shader.TileMode.CLAMP);
paint.setShader(gradient);
shapeHolder.setPaint(paint);
return shapeHolder;
}
@Override
protected void onDraw(Canvas canvas) {
canvas.save();
canvas.translate(ball.getX(), ball.getY());
ball.getShape().draw(canvas);
canvas.restore();
}
public void onAnimationUpdate(ValueAnimator animation) {
invalidate();
}
}
}