用属性动画实现小球的落地和弹起

所有代码如下:

  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 }
原文地址:https://www.cnblogs.com/csxcode/p/4187209.html