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 * See the comments in Bouncer for the overall functionality of this app. Changes for this 33 * variation are down in the animation setup code. 34 */ 35 public class Bouncer1 extends Activity { 36 37 @Override 38 public void onCreate(Bundle savedInstanceState) { 39 super.onCreate(savedInstanceState); 40 setContentView(R.layout.activity_bouncer1); 41 } 42 43 static class MyView extends View { 44 45 Bitmap mBitmap; 46 Paint paint = new Paint(); 47 int mShapeX, mShapeY; 48 int mShapeW, mShapeH; 49 50 public MyView(Context context, AttributeSet attrs, int defStyle) { 51 super(context, attrs, defStyle); 52 setupShape(); 53 } 54 55 public MyView(Context context, AttributeSet attrs) { 56 super(context, attrs); 57 setupShape(); 58 } 59 60 public MyView(Context context) { 61 super(context); 62 setupShape(); 63 } 64 65 public void setShapeX(int shapeX) { 66 int minX = mShapeX; 67 int maxX = mShapeX + mShapeW; 68 mShapeX = shapeX; 69 minX = Math.min(mShapeX, minX); 70 maxX = Math.max(mShapeX + mShapeW, maxX); 71 invalidate(minX, mShapeY, maxX, mShapeY + mShapeH); 72 } 73 74 public void setShapeY(int shapeY) { 75 int minY = mShapeY; 76 int maxY = mShapeY + mShapeH; 77 mShapeY = shapeY; 78 minY = Math.min(mShapeY, minY); 79 maxY = Math.max(mShapeY + mShapeH, maxY); 80 invalidate(mShapeX, minY, mShapeX + mShapeW, maxY); 81 } 82 83 private void setupShape() { 84 mBitmap = BitmapFactory.decodeResource(getResources(), R.drawable.electricsheep); 85 mShapeW = mBitmap.getWidth(); 86 mShapeH = mBitmap.getHeight(); 87 setOnClickListener(new View.OnClickListener() { 88 @Override 89 public void onClick(View v) { 90 startAnimation(); 91 } 92 }); 93 } 94 95 @Override 96 protected void onSizeChanged(int w, int h, int oldw, int oldh) { 97 mShapeX = (w - mBitmap.getWidth()) / 2; 98 mShapeY = 0; 99 } 100 101 @Override 102 protected void onDraw(Canvas canvas) { 103 canvas.drawBitmap(mBitmap, mShapeX, mShapeY, paint); 104 } 105 106 void startAnimation() { 107 ValueAnimator anim = getValueAnimator(); 108 // In this variation, we put the shape into an infinite bounce, where it keeps moving 109 // up and down. Note that it's still not actually "bouncing" because it just uses 110 // default time interpolation. 111 anim.setRepeatCount(ValueAnimator.INFINITE); 112 anim.setRepeatMode(ValueAnimator.REVERSE); 113 anim.start(); 114 } 115 116 ValueAnimator getValueAnimator() { 117 ValueAnimator anim = ValueAnimator.ofFloat(0, 1); 118 anim.addUpdateListener(new AnimatorUpdateListener() { 119 @Override 120 public void onAnimationUpdate(ValueAnimator animation) { 121 setShapeY((int) (animation.getAnimatedFraction() * (getHeight() - mShapeH))); 122 } 123 }); 124 return anim; 125 } 126 127 } 128 } 129