1 /* 2 * Copyright (C) 2010 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 package com.example.android.apis.animation; 18 19 // Need the following import to get access to the app resources, since this 20 // class is in a sub-package. 21 import android.animation.*; 22 import android.view.animation.AccelerateInterpolator; 23 import com.example.android.apis.R; 24 25 import java.util.ArrayList; 26 27 import android.app.Activity; 28 import android.content.Context; 29 import android.graphics.Canvas; 30 import android.graphics.Paint; 31 import android.graphics.RadialGradient; 32 import android.graphics.Shader; 33 import android.graphics.drawable.ShapeDrawable; 34 import android.graphics.drawable.shapes.OvalShape; 35 import android.os.Bundle; 36 import android.view.View; 37 import android.view.animation.BounceInterpolator; 38 import android.widget.Button; 39 import android.widget.LinearLayout; 40 41 /** 42 * This application demonstrates the seeking capability of ValueAnimator. The SeekBar in the 43 * UI allows you to set the position of the animation. Pressing the Run button will play from 44 * the current position of the animation. 45 */ 46 public class MultiPropertyAnimation extends Activity { 47 48 private static final int DURATION = 1500; 49 50 @Override onCreate(Bundle savedInstanceState)51 public void onCreate(Bundle savedInstanceState) { 52 super.onCreate(savedInstanceState); 53 setContentView(R.layout.animation_multi_property); 54 LinearLayout container = (LinearLayout) findViewById(R.id.container); 55 final MyAnimationView animView = new MyAnimationView(this); 56 container.addView(animView); 57 58 Button starter = (Button) findViewById(R.id.startButton); 59 starter.setOnClickListener(new View.OnClickListener() { 60 61 public void onClick(View v) { 62 animView.startAnimation(); 63 } 64 }); 65 66 } 67 68 public class MyAnimationView extends View implements ValueAnimator.AnimatorUpdateListener { 69 70 private static final float BALL_SIZE = 100f; 71 72 public final ArrayList<ShapeHolder> balls = new ArrayList<ShapeHolder>(); 73 AnimatorSet animation = null; 74 Animator bounceAnim = null; 75 ShapeHolder ball = null; 76 MyAnimationView(Context context)77 public MyAnimationView(Context context) { 78 super(context); 79 addBall(50, 0); 80 addBall(150, 0); 81 addBall(250, 0); 82 addBall(350, 0); 83 } 84 createAnimation()85 private void createAnimation() { 86 if (bounceAnim == null) { 87 ShapeHolder ball; 88 ball = balls.get(0); 89 ObjectAnimator yBouncer = ObjectAnimator.ofFloat(ball, "y", 90 ball.getY(), getHeight() - BALL_SIZE).setDuration(DURATION); 91 yBouncer.setInterpolator(new BounceInterpolator()); 92 yBouncer.addUpdateListener(this); 93 94 ball = balls.get(1); 95 PropertyValuesHolder pvhY = PropertyValuesHolder.ofFloat("y", ball.getY(), 96 getHeight() - BALL_SIZE); 97 PropertyValuesHolder pvhAlpha = PropertyValuesHolder.ofFloat("alpha", 1.0f, 0f); 98 ObjectAnimator yAlphaBouncer = ObjectAnimator.ofPropertyValuesHolder(ball, 99 pvhY, pvhAlpha).setDuration(DURATION/2); 100 yAlphaBouncer.setInterpolator(new AccelerateInterpolator()); 101 yAlphaBouncer.setRepeatCount(1); 102 yAlphaBouncer.setRepeatMode(ValueAnimator.REVERSE); 103 104 105 ball = balls.get(2); 106 PropertyValuesHolder pvhW = PropertyValuesHolder.ofFloat("width", ball.getWidth(), 107 ball.getWidth() * 2); 108 PropertyValuesHolder pvhH = PropertyValuesHolder.ofFloat("height", ball.getHeight(), 109 ball.getHeight() * 2); 110 PropertyValuesHolder pvTX = PropertyValuesHolder.ofFloat("x", ball.getX(), 111 ball.getX() - BALL_SIZE/2f); 112 PropertyValuesHolder pvTY = PropertyValuesHolder.ofFloat("y", ball.getY(), 113 ball.getY() - BALL_SIZE/2f); 114 ObjectAnimator whxyBouncer = ObjectAnimator.ofPropertyValuesHolder(ball, pvhW, pvhH, 115 pvTX, pvTY).setDuration(DURATION/2); 116 whxyBouncer.setRepeatCount(1); 117 whxyBouncer.setRepeatMode(ValueAnimator.REVERSE); 118 119 ball = balls.get(3); 120 pvhY = PropertyValuesHolder.ofFloat("y", ball.getY(), getHeight() - BALL_SIZE); 121 float ballX = ball.getX(); 122 Keyframe kf0 = Keyframe.ofFloat(0f, ballX); 123 Keyframe kf1 = Keyframe.ofFloat(.5f, ballX + 100f); 124 Keyframe kf2 = Keyframe.ofFloat(1f, ballX + 50f); 125 PropertyValuesHolder pvhX = PropertyValuesHolder.ofKeyframe("x", kf0, kf1, kf2); 126 ObjectAnimator yxBouncer = ObjectAnimator.ofPropertyValuesHolder(ball, pvhY, 127 pvhX).setDuration(DURATION/2); 128 yxBouncer.setRepeatCount(1); 129 yxBouncer.setRepeatMode(ValueAnimator.REVERSE); 130 131 132 bounceAnim = new AnimatorSet(); 133 ((AnimatorSet)bounceAnim).playTogether(yBouncer, yAlphaBouncer, whxyBouncer, 134 yxBouncer); 135 } 136 } 137 startAnimation()138 public void startAnimation() { 139 createAnimation(); 140 bounceAnim.start(); 141 } 142 addBall(float x, float y)143 private ShapeHolder addBall(float x, float y) { 144 OvalShape circle = new OvalShape(); 145 circle.resize(BALL_SIZE, BALL_SIZE); 146 ShapeDrawable drawable = new ShapeDrawable(circle); 147 ShapeHolder shapeHolder = new ShapeHolder(drawable); 148 shapeHolder.setX(x); 149 shapeHolder.setY(y); 150 int red = (int)(100 + Math.random() * 155); 151 int green = (int)(100 + Math.random() * 155); 152 int blue = (int)(100 + Math.random() * 155); 153 int color = 0xff000000 | red << 16 | green << 8 | blue; 154 Paint paint = drawable.getPaint(); 155 int darkColor = 0xff000000 | red/4 << 16 | green/4 << 8 | blue/4; 156 RadialGradient gradient = new RadialGradient(37.5f, 12.5f, 157 50f, color, darkColor, Shader.TileMode.CLAMP); 158 paint.setShader(gradient); 159 shapeHolder.setPaint(paint); 160 balls.add(shapeHolder); 161 return shapeHolder; 162 } 163 164 @Override onDraw(Canvas canvas)165 protected void onDraw(Canvas canvas) { 166 for (ShapeHolder ball : balls) { 167 canvas.translate(ball.getX(), ball.getY()); 168 ball.getShape().draw(canvas); 169 canvas.translate(-ball.getX(), -ball.getY()); 170 } 171 } 172 onAnimationUpdate(ValueAnimator animation)173 public void onAnimationUpdate(ValueAnimator animation) { 174 invalidate(); 175 } 176 177 } 178 }