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.Animator; 22 import com.example.android.apis.R; 23 24 import java.util.ArrayList; 25 26 import android.animation.ValueAnimator; 27 import android.animation.ObjectAnimator; 28 import android.animation.AnimatorSet; 29 import android.app.Activity; 30 import android.content.Context; 31 import android.graphics.Canvas; 32 import android.graphics.Paint; 33 import android.graphics.RadialGradient; 34 import android.graphics.Shader; 35 import android.graphics.drawable.ShapeDrawable; 36 import android.graphics.drawable.shapes.OvalShape; 37 import android.os.Bundle; 38 import android.view.View; 39 import android.view.animation.BounceInterpolator; 40 import android.widget.Button; 41 import android.widget.LinearLayout; 42 import android.widget.SeekBar; 43 44 /** 45 * This application demonstrates the seeking capability of ValueAnimator. The SeekBar in the 46 * UI allows you to set the position of the animation. Pressing the Run button will play from 47 * the current position of the animation. 48 */ 49 public class AnimationSeeking extends Activity { 50 51 private static final int DURATION = 1500; 52 private SeekBar mSeekBar; 53 54 /** Called when the activity is first created. */ 55 @Override 56 public void onCreate(Bundle savedInstanceState) { 57 super.onCreate(savedInstanceState); 58 setContentView(R.layout.animation_seeking); 59 LinearLayout container = (LinearLayout) findViewById(R.id.container); 60 final MyAnimationView animView = new MyAnimationView(this); 61 container.addView(animView); 62 63 Button starter = (Button) findViewById(R.id.startButton); 64 starter.setOnClickListener(new View.OnClickListener() { 65 public void onClick(View v) { 66 animView.startAnimation(); 67 } 68 }); 69 70 mSeekBar = (SeekBar) findViewById(R.id.seekBar); 71 mSeekBar.setMax(DURATION); 72 mSeekBar.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() { 73 public void onStopTrackingTouch(SeekBar seekBar) { 74 } 75 76 public void onStartTrackingTouch(SeekBar seekBar) { 77 } 78 79 public void onProgressChanged(SeekBar seekBar, int progress, 80 boolean fromUser) { 81 // prevent seeking on app creation 82 if (animView.getHeight() != 0) { 83 animView.seek(progress); 84 } 85 } 86 }); 87 } 88 89 public class MyAnimationView extends View implements ValueAnimator.AnimatorUpdateListener, Animator.AnimatorListener { 90 91 private static final int RED = 0xffFF8080; 92 private static final int BLUE = 0xff8080FF; 93 private static final int CYAN = 0xff80ffff; 94 private static final int GREEN = 0xff80ff80; 95 private static final float BALL_SIZE = 100f; 96 97 public final ArrayList<ShapeHolder> balls = new ArrayList<ShapeHolder>(); 98 AnimatorSet animation = null; 99 ValueAnimator bounceAnim = null; 100 ShapeHolder ball = null; 101 102 public MyAnimationView(Context context) { 103 super(context); 104 ball = addBall(200, 0); 105 } 106 107 private void createAnimation() { 108 if (bounceAnim == null) { 109 bounceAnim = ObjectAnimator.ofFloat(ball, "y", 110 ball.getY(), getHeight() - BALL_SIZE).setDuration(1500); 111 bounceAnim.setInterpolator(new BounceInterpolator()); 112 bounceAnim.addUpdateListener(this); 113 } 114 } 115 116 public void startAnimation() { 117 createAnimation(); 118 bounceAnim.start(); 119 } 120 121 public void seek(long seekTime) { 122 createAnimation(); 123 bounceAnim.setCurrentPlayTime(seekTime); 124 } 125 126 private ShapeHolder addBall(float x, float y) { 127 OvalShape circle = new OvalShape(); 128 circle.resize(BALL_SIZE, BALL_SIZE); 129 ShapeDrawable drawable = new ShapeDrawable(circle); 130 ShapeHolder shapeHolder = new ShapeHolder(drawable); 131 shapeHolder.setX(x); 132 shapeHolder.setY(y); 133 int red = (int)(100 + Math.random() * 155); 134 int green = (int)(100 + Math.random() * 155); 135 int blue = (int)(100 + Math.random() * 155); 136 int color = 0xff000000 | red << 16 | green << 8 | blue; 137 Paint paint = drawable.getPaint(); 138 int darkColor = 0xff000000 | red/4 << 16 | green/4 << 8 | blue/4; 139 RadialGradient gradient = new RadialGradient(37.5f, 12.5f, 140 50f, color, darkColor, Shader.TileMode.CLAMP); 141 paint.setShader(gradient); 142 shapeHolder.setPaint(paint); 143 balls.add(shapeHolder); 144 return shapeHolder; 145 } 146 147 @Override 148 protected void onDraw(Canvas canvas) { 149 canvas.translate(ball.getX(), ball.getY()); 150 ball.getShape().draw(canvas); 151 } 152 153 public void onAnimationUpdate(ValueAnimator animation) { 154 invalidate(); 155 long playtime = bounceAnim.getCurrentPlayTime(); 156 //mSeekBar.setProgress((int)playtime); 157 } 158 159 public void onAnimationCancel(Animator animation) { 160 } 161 162 public void onAnimationEnd(Animator animation) { 163 balls.remove(((ObjectAnimator)animation).getTarget()); 164 165 } 166 167 public void onAnimationRepeat(Animator animation) { 168 } 169 170 public void onAnimationStart(Animator animation) { 171 } 172 } 173 }