Created
June 20, 2014 00:49
-
-
Save ishitcno1/d907865d3ff1f746a702 to your computer and use it in GitHub Desktop.
android property animation bouncing balls
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?xml version="1.0" encoding="utf-8"?> | |
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" | |
android:layout_width="match_parent" | |
android:layout_height="match_parent" | |
android:orientation="vertical" | |
android:id="@+id/ac_bouncing_balls_container"> | |
</LinearLayout> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
public class BouncingBallsActivity extends Activity { | |
@Override | |
protected void onCreate(Bundle savedInstanceState) { | |
super.onCreate(savedInstanceState); | |
setContentView(R.layout.ac_bouncing_balls); | |
LinearLayout container = (LinearLayout) findViewById(R.id.ac_bouncing_balls_container); | |
container.addView(new MyAnimationView(this)); | |
} | |
public class MyAnimationView extends View { | |
private static final int RED = 0xffff0000; | |
private static final int BLUE = 0xff0000ff; | |
private ArrayList<Ball> balls = new ArrayList<Ball>(); | |
public MyAnimationView(Context context) { | |
super(context); | |
// Animate background color | |
// Note that setting the background color will automatically invalidate the | |
// view, so that the animated color, and the bouncing balls, get redisplayed on | |
// every frame of the animation. | |
ValueAnimator colorAnim = ObjectAnimator.ofInt(this, "backgroundColor", RED, BLUE); | |
colorAnim.setDuration(3000); | |
colorAnim.setEvaluator(new ArgbEvaluator()); | |
colorAnim.setRepeatCount(ValueAnimator.INFINITE); | |
colorAnim.setRepeatMode(ValueAnimator.REVERSE); | |
colorAnim.start(); | |
} | |
@Override | |
public boolean onTouchEvent(MotionEvent event) { | |
if (event.getAction() == MotionEvent.ACTION_DOWN || | |
event.getAction() == MotionEvent.ACTION_MOVE) { | |
Ball newBall = addBall(event.getX(), event.getY()); | |
float startY = newBall.getY(); | |
float height = getHeight(); | |
float endY = height - 50f; | |
int duration = (int) (800 * ((height - startY) / height)); | |
ObjectAnimator bounceAnim = ObjectAnimator.ofFloat(newBall, "y", startY, endY); | |
bounceAnim.setDuration(duration); | |
bounceAnim.setInterpolator(new AccelerateInterpolator()); | |
ObjectAnimator squashHeightAnim = ObjectAnimator.ofFloat(newBall, "height", | |
newBall.getHeight(), newBall.getHeight() - 12.5f); | |
squashHeightAnim.setDuration(duration / 4); | |
squashHeightAnim.setInterpolator(new DecelerateInterpolator()); | |
squashHeightAnim.setRepeatCount(1); | |
squashHeightAnim.setRepeatMode(ValueAnimator.REVERSE); | |
ObjectAnimator stretchWidthAnim = ObjectAnimator.ofFloat(newBall, "width", | |
newBall.getWidth(), newBall.getWidth() + 12.5f); | |
stretchWidthAnim.setDuration(duration / 4); | |
stretchWidthAnim.setInterpolator(new DecelerateInterpolator()); | |
stretchWidthAnim.setRepeatCount(1); | |
stretchWidthAnim.setRepeatMode(ValueAnimator.REVERSE); | |
ObjectAnimator bounceBackAnim = ObjectAnimator.ofFloat(newBall, "y", | |
endY, startY); | |
bounceBackAnim.setDuration(duration); | |
bounceBackAnim.setInterpolator(new DecelerateInterpolator()); | |
ObjectAnimator fadeAnim = ObjectAnimator.ofFloat(newBall, "alpha", 1f, 0f); | |
fadeAnim.setDuration(duration / 4); | |
fadeAnim.addListener(new AnimatorListenerAdapter() { | |
@Override | |
public void onAnimationEnd(Animator animation) { | |
balls.remove(((ObjectAnimator) animation).getTarget()); | |
} | |
}); | |
AnimatorSet animatorSet = new AnimatorSet(); | |
animatorSet.play(bounceAnim).before(squashHeightAnim); | |
animatorSet.play(squashHeightAnim).with(stretchWidthAnim); | |
animatorSet.play(bounceBackAnim).after(squashHeightAnim); | |
animatorSet.play(fadeAnim).after(bounceBackAnim); | |
animatorSet.start(); | |
return true; | |
} else { | |
return false; | |
} | |
} | |
@Override | |
protected void onDraw(Canvas canvas) { | |
for (Ball ball : balls) { | |
canvas.save(); | |
canvas.translate(ball.getX(), ball.getY()); | |
ball.getShapeDrawable().draw(canvas); | |
canvas.restore(); | |
} | |
} | |
private Ball addBall(float x, float y) { | |
Ball ball = new Ball(); | |
ball.setX(x - 25f); | |
ball.setY(y - 25f); | |
balls.add(ball); | |
return ball; | |
} | |
} | |
public class Ball { | |
private float x; | |
private float y; | |
private Shape shape; | |
private ShapeDrawable shapeDrawable; | |
private Paint paint; | |
public Ball() { | |
shape = new OvalShape(); | |
shape.resize(50f, 50f); | |
shapeDrawable = new ShapeDrawable(shape); | |
paint = shapeDrawable.getPaint(); | |
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.setColor(color); | |
} | |
public float getY() { | |
return y; | |
} | |
public void setY(float y) { | |
this.y = y; | |
} | |
public float getX() { | |
return x; | |
} | |
public void setX(float x) { | |
this.x = x; | |
} | |
public ShapeDrawable getShapeDrawable() { | |
return shapeDrawable; | |
} | |
public float getWidth() { | |
return shape.getWidth(); | |
} | |
public void setWidth(float width) { | |
shape.resize(width, shape.getHeight()); | |
} | |
public float getHeight() { | |
return shape.getHeight(); | |
} | |
public void setHeight(float height) { | |
shape.resize(shape.getWidth(), height); | |
} | |
public void setAlpha(float alpha) { | |
shapeDrawable.setAlpha((int) (alpha * 255f + 0.5f)); | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment