这个可以说是对以前动画的温习,最后一个球的运动需要注意一下, 最后一个 使用到了 keyframe 关键帧的 东西 很类似 flash的关键帧
public class MultiPropertyAnimation extends Activity {private static final int DURATION = 1500;@Overridepublic void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.animation_multi_property);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 MyAnimationView extends View implements ValueAnimator.AnimatorUpdateListener {private static final float BALL_SIZE = 100f;public final ArrayList<ShapeHolder> balls = new ArrayList<ShapeHolder>();AnimatorSet animation = null;Animator bounceAnim = null;ShapeHolder ball = null;public MyAnimationView(Context context) {super(context);addBall(50, 0);addBall(150, 0);addBall(250, 0);addBall(350, 0);}private void createAnimation() {if (bounceAnim == null) {//1球和2球 展示了 用两种方式播放上下动画ShapeHolder ball;ball = balls.get(0);ObjectAnimator yBouncer = ObjectAnimator.ofFloat(ball, "y",ball.getY(), getHeight() - BALL_SIZE).setDuration(DURATION);yBouncer.setInterpolator(new CycleInterpolator(1));yBouncer.addUpdateListener(this);yBouncer.setRepeatCount(ObjectAnimator.INFINITE);ball = balls.get(1);PropertyValuesHolder pvhY = PropertyValuesHolder.ofFloat("y", ball.getY(),getHeight() - BALL_SIZE);PropertyValuesHolder pvhAlpha = PropertyValuesHolder.ofFloat("alpha", 1.0f, 0f);ObjectAnimator yAlphaBouncer = ObjectAnimator.ofPropertyValuesHolder(ball,pvhY, pvhAlpha).setDuration(DURATION/2);yAlphaBouncer.setInterpolator(new AccelerateInterpolator());yAlphaBouncer.setRepeatCount(ObjectAnimator.INFINITE);yAlphaBouncer.setRepeatMode(ValueAnimator.REVERSE);//设置球的大小 并调整使其居中ball = balls.get(2);PropertyValuesHolder pvhW = PropertyValuesHolder.ofFloat("width", ball.getWidth(),ball.getWidth() * 2);PropertyValuesHolder pvhH = PropertyValuesHolder.ofFloat("height", ball.getHeight(),ball.getHeight() * 2);PropertyValuesHolder pvTX = PropertyValuesHolder.ofFloat("x", ball.getX(),ball.getX() - BALL_SIZE/2f);PropertyValuesHolder pvTY = PropertyValuesHolder.ofFloat("y", ball.getY(),ball.getY() - BALL_SIZE/2f);ObjectAnimator whxyBouncer = ObjectAnimator.ofPropertyValuesHolder(ball, pvhW, pvhH,pvTX, pvTY).setDuration(DURATION/2);whxyBouncer.setRepeatCount(ObjectAnimator.INFINITE);whxyBouncer.setRepeatMode(ValueAnimator.REVERSE);//ball = balls.get(3);pvhY = PropertyValuesHolder.ofFloat("y", ball.getY(), getHeight() - BALL_SIZE);//上下跳动float ballX = ball.getX();Keyframe kf0 = Keyframe.ofFloat(0f, ballX);//在 动画 开始的时候 x的 关键帧位置Keyframe kf1 = Keyframe.ofFloat(.5f, ballX + 100f); //在动画一半的时候x的位置Keyframe kf2 = Keyframe.ofFloat(1f, ballX + 50f); //在动画结束的时候 x的位置PropertyValuesHolder pvhX = PropertyValuesHolder.ofKeyframe("x", kf0, kf1, kf2);//设定x的播放位置ObjectAnimator yxBouncer = ObjectAnimator.ofPropertyValuesHolder(ball, pvhY,pvhX).setDuration(DURATION/2);//设置xy的轨迹yxBouncer.setRepeatCount(ObjectAnimator.INFINITE);yxBouncer.setRepeatMode(ValueAnimator.REVERSE);bounceAnim = new AnimatorSet();((AnimatorSet)bounceAnim).playTogether(yBouncer, yAlphaBouncer, whxyBouncer,yxBouncer);}}public void startAnimation() {createAnimation();bounceAnim.start();}private ShapeHolder addBall(float x, float y) {OvalShape circle = new OvalShape();circle.resize(BALL_SIZE, BALL_SIZE);ShapeDrawable drawable = new ShapeDrawable(circle);ShapeHolder shapeHolder = new ShapeHolder(drawable);shapeHolder.setX(x);shapeHolder.setY(y);int red = (int)(100 + Math.random() * 155);int green = (int)(100 + Math.random() * 155);int blue = (int)(100 + Math.random() * 155);int color = 0xff000000 | red << 16 | green << 8 | blue;Paint paint = drawable.getPaint();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);balls.add(shapeHolder);return shapeHolder;}@Overrideprotected void onDraw(Canvas canvas) {for (ShapeHolder ball : balls) {canvas.translate(ball.getX(), ball.getY());ball.getShape().draw(canvas);canvas.translate(-ball.getX(), -ball.getY());}}public void onAnimationUpdate(ValueAnimator animation) {invalidate();}}
}
展示了animator 播放后还可以返回,在动画过程中甚至也可以返回
public class ReversingAnimation extends Activity {@Overridepublic void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.animation_reversing);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();}});Button reverser = (Button) findViewById(R.id.reverseButton);reverser.setOnClickListener(new View.OnClickListener() {public void onClick(View v) {animView.reverseAnimation();}});}public class MyAnimationView extends View implements ValueAnimator.AnimatorUpdateListener {public final ArrayList<ShapeHolder> balls = new ArrayList<ShapeHolder>();ValueAnimator bounceAnim = null;ShapeHolder ball = null;public MyAnimationView(Context context) {super(context);ball = createBall(25, 25);}private void createAnimation() {if (bounceAnim == null) {bounceAnim = ObjectAnimator.ofFloat(ball, "y", ball.getY(), getHeight() - 50f).setDuration(1500);bounceAnim.setInterpolator(new AccelerateInterpolator(2f));bounceAnim.addUpdateListener(this);}}public void startAnimation() {createAnimation();bounceAnim.start();}public void reverseAnimation() {createAnimation();bounceAnim.reverse();}public void seek(long seekTime) {createAnimation();bounceAnim.setCurrentPlayTime(seekTime);}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;}@Overrideprotected void onDraw(Canvas canvas) {canvas.save();canvas.translate(ball.getX(), ball.getY());ball.getShape().draw(canvas);canvas.restore();}public void onAnimationUpdate(ValueAnimator animation) {invalidate();}}
}