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


    所有代码如下:

      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 }
  • 相关阅读:
    基础练习 数列排序
    入门训练 Fibonacci数列
    入门训练 圆的面积
    入门训练 序列求和
    fzu 2111 Min Number
    入门训练 A+B问题
    历届试题 城市建设
    sort 树 hash 排序
    nyist 676 小明的求助
    快速幂 蒙格马利算法
  • 原文地址:https://www.cnblogs.com/csxcode/p/4187209.html
Copyright © 2020-2023  润新知