1 /* 2 * Copyright (C) 2013 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.bouncer; 18 19 import android.animation.ValueAnimator; 20 import android.animation.ValueAnimator.AnimatorUpdateListener; 21 import android.app.Activity; 22 import android.content.Context; 23 import android.graphics.Bitmap; 24 import android.graphics.BitmapFactory; 25 import android.graphics.Canvas; 26 import android.graphics.Paint; 27 import android.os.Bundle; 28 import android.util.AttributeSet; 29 import android.view.View; 30 31 /** 32 * This example shows simple uses of ValueAnimator, ObjectAnimator, and interpolators 33 * to control how a shape is moved around on the screen. 34 * 35 * The Bouncer1, Bouncer2, and Vouncer3 files are exactly like this one except for variations 36 * in how the animation is set up and run. 37 * 38 * Watch the associated video for this demo on the DevBytes channel of developer.android.com 39 * or on YouTube at https://www.youtube.com/watch?v=vCTcmPIKgpM. 40 */ 41 public class Bouncer extends Activity { 42 43 @Override onCreate(Bundle savedInstanceState)44 public void onCreate(Bundle savedInstanceState) { 45 super.onCreate(savedInstanceState); 46 setContentView(R.layout.activity_bouncer); 47 } 48 49 /** 50 * A custom view is used to paint the green background and the shape. 51 */ 52 static class MyView extends View { 53 54 Bitmap mBitmap; 55 Paint paint = new Paint(); 56 int mShapeX, mShapeY; 57 int mShapeW, mShapeH; 58 MyView(Context context, AttributeSet attrs, int defStyle)59 public MyView(Context context, AttributeSet attrs, int defStyle) { 60 super(context, attrs, defStyle); 61 setupShape(); 62 } 63 MyView(Context context, AttributeSet attrs)64 public MyView(Context context, AttributeSet attrs) { 65 super(context, attrs); 66 setupShape(); 67 } 68 MyView(Context context)69 public MyView(Context context) { 70 super(context); 71 setupShape(); 72 } 73 setupShape()74 private void setupShape() { 75 mBitmap = BitmapFactory.decodeResource(getResources(), 76 R.drawable.electricsheep); 77 mShapeW = mBitmap.getWidth(); 78 mShapeH = mBitmap.getHeight(); 79 setOnClickListener(new View.OnClickListener() { 80 @Override 81 public void onClick(View v) { 82 startAnimation(); 83 } 84 }); 85 } 86 87 /** 88 * Moving the shape in x or y causes an invalidation of the area it used to occupy 89 * plus the area it now occupies. 90 */ setShapeX(int shapeX)91 public void setShapeX(int shapeX) { 92 int minX = mShapeX; 93 int maxX = mShapeX + mShapeW; 94 mShapeX = shapeX; 95 minX = Math.min(mShapeX, minX); 96 maxX = Math.max(mShapeX + mShapeW, maxX); 97 invalidate(minX, mShapeY, maxX, mShapeY + mShapeH); 98 } 99 100 /** 101 * Moving the shape in x or y causes an invalidation of the area it used to occupy 102 * plus the area it now occupies. 103 */ setShapeY(int shapeY)104 public void setShapeY(int shapeY) { 105 int minY = mShapeY; 106 int maxY = mShapeY + mShapeH; 107 mShapeY = shapeY; 108 minY = Math.min(mShapeY, minY); 109 maxY = Math.max(mShapeY + mShapeH, maxY); 110 invalidate(mShapeX, minY, mShapeX + mShapeW, maxY); 111 } 112 113 @Override onSizeChanged(int w, int h, int oldw, int oldh)114 protected void onSizeChanged(int w, int h, int oldw, int oldh) { 115 mShapeX = (w - mBitmap.getWidth()) / 2; 116 mShapeY = 0; 117 } 118 119 @Override onDraw(Canvas canvas)120 protected void onDraw(Canvas canvas) { 121 canvas.drawBitmap(mBitmap, mShapeX, mShapeY, paint); 122 } 123 startAnimation()124 void startAnimation() { 125 // This version uses ValueAnimator, which requires adding an update 126 // listener and manually updating the shape position on each frame. 127 ValueAnimator anim = getValueAnimator(); 128 anim.start(); 129 } 130 getValueAnimator()131 ValueAnimator getValueAnimator() { 132 ValueAnimator anim = ValueAnimator.ofFloat(0, 1); 133 anim.addUpdateListener(new AnimatorUpdateListener() { 134 @Override 135 public void onAnimationUpdate(ValueAnimator animation) { 136 setShapeY((int) (animation.getAnimatedFraction() * 137 (getHeight() - mShapeH))); 138 } 139 }); 140 return anim; 141 } 142 143 } 144 } 145