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