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.ObjectAnimator; 20 import android.animation.ValueAnimator; 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 import android.view.animation.AccelerateInterpolator; 31 32 /** 33 * See the comments in Bouncer for the overall functionality of this app. Changes for this 34 * variation are down in the animation setup code. 35 */ 36 public class Bouncer3 extends Activity { 37 38 @Override 39 public void onCreate(Bundle savedInstanceState) { 40 super.onCreate(savedInstanceState); 41 setContentView(R.layout.activity_bouncer3); 42 } 43 44 static class MyView extends View { 45 46 Bitmap mBitmap; 47 Paint paint = new Paint(); 48 int mShapeX, mShapeY; 49 int mShapeW, mShapeH; 50 51 public MyView(Context context, AttributeSet attrs, int defStyle) { 52 super(context, attrs, defStyle); 53 setupShape(); 54 } 55 56 public MyView(Context context, AttributeSet attrs) { 57 super(context, attrs); 58 setupShape(); 59 } 60 61 public MyView(Context context) { 62 super(context); 63 setupShape(); 64 } 65 66 public void setShapeX(int shapeX) { 67 int minX = mShapeX; 68 int maxX = mShapeX + mShapeW; 69 mShapeX = shapeX; 70 minX = Math.min(mShapeX, minX); 71 maxX = Math.max(mShapeX + mShapeW, maxX); 72 invalidate(minX, mShapeY, maxX, mShapeY + mShapeH); 73 } 74 75 public void setShapeY(int shapeY) { 76 int minY = mShapeY; 77 int maxY = mShapeY + mShapeH; 78 mShapeY = shapeY; 79 minY = Math.min(mShapeY, minY); 80 maxY = Math.max(mShapeY + mShapeH, maxY); 81 invalidate(mShapeX, minY, mShapeX + mShapeW, maxY); 82 } 83 84 private void setupShape() { 85 mBitmap = BitmapFactory.decodeResource(getResources(), R.drawable.electricsheep); 86 mShapeW = mBitmap.getWidth(); 87 mShapeH = mBitmap.getHeight(); 88 setOnClickListener(new View.OnClickListener() { 89 @Override 90 public void onClick(View v) { 91 startAnimation(); 92 } 93 }); 94 } 95 96 @Override 97 protected void onSizeChanged(int w, int h, int oldw, int oldh) { 98 mShapeX = (w - mBitmap.getWidth()) / 2; 99 mShapeY = 0; 100 } 101 102 @Override 103 protected void onDraw(Canvas canvas) { 104 canvas.drawBitmap(mBitmap, mShapeX, mShapeY, paint); 105 } 106 107 void startAnimation() { 108 // This variation uses an ObjectAnimator. The functionality is exactly the same as 109 // in Bouncer2, but this time the boilerplate code is greatly reduced because we 110 // tell ObjectAnimator to automatically animate the target object for us, so we no 111 // longer need to listen for frame updates and do that work ourselves. 112 ObjectAnimator anim = getObjectAnimator(); 113 anim.setRepeatCount(ValueAnimator.INFINITE); 114 anim.setRepeatMode(ValueAnimator.REVERSE); 115 anim.setInterpolator(new AccelerateInterpolator()); 116 anim.start(); 117 } 118 119 ObjectAnimator getObjectAnimator() { 120 return ObjectAnimator.ofInt(this, "shapeY", 0, (getHeight() - mShapeH)); 121 } 122 123 } 124 } 125