所有代码如下:
1 package com.example.animation; 2 3 import android.animation.Animator; 4 import android.animation.AnimatorListenerAdapter; 5 import android.animation.AnimatorSet; 6 import android.animation.ObjectAnimator; 7 import android.animation.ValueAnimator; 8 import android.animation.ValueAnimator.AnimatorUpdateListener; 9 import android.app.Activity; 10 import android.content.Context; 11 import android.graphics.Canvas; 12 import android.graphics.Color; 13 import android.graphics.Paint; 14 import android.graphics.RadialGradient; 15 import android.graphics.Shader; 16 import android.graphics.drawable.ShapeDrawable; 17 import android.graphics.drawable.shapes.OvalShape; 18 import android.os.Bundle; 19 import android.util.Log; 20 import android.view.MotionEvent; 21 import android.view.View; 22 import android.view.ViewGroup; 23 import android.view.ViewGroup.LayoutParams; 24 import android.view.animation.AccelerateDecelerateInterpolator; 25 import android.view.animation.DecelerateInterpolator; 26 import android.widget.LinearLayout; 27 28 import java.util.ArrayList; 29 30 public class AnimatorTest extends Activity { 31 static final float BALL_SIZE = 50f; 32 static final float FULL_TIME = 500; 33 34 @Override 35 protected void onCreate(Bundle savedInstanceState) { 36 super.onCreate(savedInstanceState); 37 38 LinearLayout container = new LinearLayout(this); 39 ViewGroup.LayoutParams lp = new LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, 40 ViewGroup.LayoutParams.MATCH_PARENT); 41 container.addView(new MyAnimationView(this), lp); 42 setContentView(container); 43 44 } 45 46 public class MyAnimationView extends View implements AnimatorUpdateListener { 47 48 public final ArrayList<ShapeHolder> balls = new ArrayList<ShapeHolder>(); 49 50 public MyAnimationView(Context context) { 51 super(context); 52 setBackgroundColor(Color.WHITE); 53 } 54 55 @Override 56 protected void onDraw(Canvas canvas) { 57 for (ShapeHolder shapeHolder : balls) { 58 canvas.save(); 59 60 canvas.translate(shapeHolder.getX(), shapeHolder.getY()); 61 shapeHolder.getShap().draw(canvas); 62 canvas.restore(); 63 64 } 65 66 } 67 68 @Override 69 public boolean onTouchEvent(MotionEvent event) { 70 if (event.getAction() != MotionEvent.ACTION_DOWN 71 && event.getAction() != MotionEvent.ACTION_MOVE) { 72 return false; 73 74 } 75 ShapeHolder newBall = addBall(event.getX(), event.getY()); 76 77 float h = getHeight();// 屏幕高度 78 float startY = newBall.getY(); 79 float endY = h - BALL_SIZE; 80 81 int duration = (int) (FULL_TIME * ((h - event.getY()) / h)); 82 if (duration < 0) { 83 duration = 0; 84 } 85 86 // 定义下落的属性动画///////////////////////////////////////////////////////////////////////// 87 ValueAnimator fallAnim = ObjectAnimator.ofFloat(newBall, "y", startY, endY); 88 fallAnim.setDuration(duration); 89 fallAnim.setInterpolator(new AccelerateDecelerateInterpolator());// 加速插值 90 fallAnim.addUpdateListener(this); 91 92 // 定义小球压扁的属性动画:画布位置左移,宽度拉长///////////////////////////////////////////////////////////////////////// 93 ValueAnimator squashAnim1 = ObjectAnimator.ofFloat(newBall, "x", newBall.getX(), 94 newBall.getX() - BALL_SIZE / 2); 95 squashAnim1.setDuration(duration / 4); 96 squashAnim1.setInterpolator(new DecelerateInterpolator()); 97 squashAnim1.setRepeatCount(1); 98 squashAnim1.setRepeatMode(ValueAnimator.REVERSE); 99 squashAnim1.addUpdateListener(this); 100 101 ValueAnimator squashAnim2 = ObjectAnimator.ofFloat(newBall, "width", 102 newBall.getWidth(), 103 newBall.getWidth() + BALL_SIZE / 2); 104 squashAnim2.setDuration(duration / 4); 105 squashAnim2.setInterpolator(new DecelerateInterpolator()); 106 squashAnim2.setRepeatCount(1); 107 squashAnim2.setRepeatMode(ValueAnimator.REVERSE); 108 squashAnim2.addUpdateListener(this); 109 // 定义小球拉伸的属性动画:画布位置下移,高度压低///////////////////////////////////////////////////////////////////////// 110 ValueAnimator stretchAnim1 = ObjectAnimator.ofFloat(newBall, "y", 111 endY, 112 endY + BALL_SIZE / 2); 113 stretchAnim1.setDuration(duration / 4); 114 stretchAnim1.setInterpolator(new DecelerateInterpolator()); 115 stretchAnim1.setRepeatCount(1); 116 stretchAnim1.setRepeatMode(ValueAnimator.REVERSE); 117 stretchAnim1.addUpdateListener(this); 118 119 ValueAnimator stretchAnim2 = ObjectAnimator.ofFloat(newBall, "height", 120 newBall.getHeight(), 121 newBall.getHeight() - BALL_SIZE / 2); 122 stretchAnim2.setDuration(duration / 4); 123 stretchAnim2.setInterpolator(new DecelerateInterpolator()); 124 stretchAnim2.setRepeatCount(1); 125 stretchAnim2.setRepeatMode(ValueAnimator.REVERSE); 126 stretchAnim2.addUpdateListener(this); 127 // 定义小球弹起的属性动画:///////////////////////////////////////////////////////////////////////// 128 ValueAnimator bounceBackAnim = ObjectAnimator.ofFloat(newBall, "y", 129 endY, 130 startY); 131 bounceBackAnim.setDuration(duration); 132 bounceBackAnim.setInterpolator(new DecelerateInterpolator()); 133 bounceBackAnim.addUpdateListener(this); 134 135 // 定义渐隐的属性动画///////////////////////////////////////////////////////////////////////// 136 ObjectAnimator fadeAnim = ObjectAnimator.ofFloat(newBall, "alpha", 1f, 0f); 137 fadeAnim.setDuration(250); 138 fadeAnim.addUpdateListener(this); 139 fadeAnim.addListener(new AnimatorListenerAdapter() { 140 141 @Override 142 public void onAnimationEnd(Animator animation) { 143 balls.remove(((ObjectAnimator) animation).getTarget()); 144 } 145 146 }); 147 148 // 定义属性动画集合:掉落--压扁&拉伸--弹起///////////////////////////////////////////////////////////////////////// 149 AnimatorSet bouncer = new AnimatorSet(); 150 bouncer.play(fallAnim).before(squashAnim1); 151 bouncer.play(squashAnim1).with(squashAnim2).with(stretchAnim1).with(stretchAnim2); 152 bouncer.play(bounceBackAnim).after(squashAnim1); 153 // 属性动画集合,将上面的bouncer和fadeAnim组合起来,并安排顺序 154 AnimatorSet set = new AnimatorSet(); 155 set.play(bouncer).before(fadeAnim); 156 set.start(); 157 158 return true; 159 } 160 161 @Override 162 public void onAnimationUpdate(ValueAnimator animation) { 163 this.invalidate(); 164 165 } 166 167 public ShapeHolder addBall(float x, float y) { 168 169 OvalShape circle = new OvalShape(); 170 circle.resize(BALL_SIZE, BALL_SIZE); 171 ShapeDrawable shape = new ShapeDrawable(circle);// 将圆包装成drawable对象 172 ShapeHolder shapeHolder = new ShapeHolder(shape); 173 174 shapeHolder.setX(x - BALL_SIZE / 2); 175 shapeHolder.setY(y - BALL_SIZE / 2); 176 177 int red = (int) (Math.random() * 255); 178 int green = (int) (Math.random() * 255); 179 int blue = (int) (Math.random() * 255); 180 181 int color = 0xff000000 + ((red << 16) | (green << 8) | blue); 182 int darkColor = 0xff000000 + (((red / 4) << 16) | (green / 4 << 8) | (blue / 4)); 183 184 Paint paint = shape.getPaint(); 185 RadialGradient radialGradient = new RadialGradient(x, y, BALL_SIZE, color, darkColor, 186 Shader.TileMode.CLAMP); 187 paint.setShader(radialGradient); 188 189 shapeHolder.setPaint(paint); 190 191 balls.add(shapeHolder); 192 193 return shapeHolder; 194 } 195 196 } 197 198 }
1 package com.example.animation; 2 3 import android.graphics.Paint; 4 import android.graphics.RadialGradient; 5 import android.graphics.drawable.ShapeDrawable; 6 import android.graphics.drawable.shapes.Shape; 7 8 public class ShapeHolder { 9 private float x = 0, y = 0;// 注意此处的x和y是画布开始的位置 10 private ShapeDrawable shap; 11 private int color; 12 private RadialGradient gradient; // 环形渐变 13 private float alpha = 1f; 14 private Paint paint; 15 16 ShapeHolder(ShapeDrawable s) { 17 this.shap = s; 18 } 19 20 public float getWidth() { 21 return shap.getShape().getWidth(); 22 } 23 24 public void setWidth(float width) { 25 Shape s = shap.getShape(); 26 s.resize(width, s.getHeight()); 27 } 28 29 public float getHeight() { 30 return shap.getShape().getHeight(); 31 } 32 33 public void setHeight(float height) { 34 Shape s = shap.getShape(); 35 s.resize(s.getWidth(), height); 36 } 37 38 public float getX() { 39 return x; 40 } 41 42 public void setX(float x) { 43 this.x = x; 44 } 45 46 public float getY() { 47 return y; 48 } 49 50 public void setY(float y) { 51 this.y = y; 52 } 53 54 public ShapeDrawable getShap() { 55 return shap; 56 } 57 58 public void setShap(ShapeDrawable shap) { 59 this.shap = shap; 60 } 61 62 public int getColor() { 63 return color; 64 } 65 66 public void setColor(int color) { 67 this.color = color; 68 } 69 70 public RadialGradient getGradient() { 71 return gradient; 72 } 73 74 public void setGradient(RadialGradient gradient) { 75 this.gradient = gradient; 76 } 77 78 public float getAlpha() { 79 return alpha; 80 } 81 82 public void setAlpha(float alpha) { 83 this.alpha = alpha; 84 } 85 86 public Paint getPaint() { 87 return paint; 88 } 89 90 public void setPaint(Paint paint) { 91 this.paint = paint; 92 } 93 94 }