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 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 Bouncer2 extends Activity {
37 
38     @Override
onCreate(Bundle savedInstanceState)39     public void onCreate(Bundle savedInstanceState) {
40         super.onCreate(savedInstanceState);
41         setContentView(R.layout.activity_bouncer2);
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 
MyView(Context context, AttributeSet attrs, int defStyle)51         public MyView(Context context, AttributeSet attrs, int defStyle) {
52             super(context, attrs, defStyle);
53             setupShape();
54         }
55 
MyView(Context context, AttributeSet attrs)56         public MyView(Context context, AttributeSet attrs) {
57             super(context, attrs);
58             setupShape();
59         }
60 
MyView(Context context)61         public MyView(Context context) {
62             super(context);
63             setupShape();
64         }
65 
setShapeX(int shapeX)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 
setShapeY(int shapeY)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 
setupShape()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
onSizeChanged(int w, int h, int oldw, int oldh)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
onDraw(Canvas canvas)103         protected void onDraw(Canvas canvas) {
104             canvas.drawBitmap(mBitmap, mShapeX, mShapeY, paint);
105         }
106 
startAnimation()107         void startAnimation() {
108             ValueAnimator anim = getValueAnimator();
109             anim.setRepeatCount(ValueAnimator.INFINITE);
110             anim.setRepeatMode(ValueAnimator.REVERSE);
111             // This variation finally has the shape bouncing, due to the use of an
112             // AccelerateInterpolator, which speeds up as the animation proceed. Note that
113             // when the animation reverses, the interpolator acts in reverse, decelerating
114             // movement.
115             anim.setInterpolator(new AccelerateInterpolator());
116             anim.start();
117         }
118 
getValueAnimator()119         ValueAnimator getValueAnimator() {
120             ValueAnimator anim = ValueAnimator.ofFloat(0, 1);
121             anim.addUpdateListener(new AnimatorUpdateListener() {
122                 @Override
123                 public void onAnimationUpdate(ValueAnimator animation) {
124                     setShapeY((int) (animation.getAnimatedFraction() * (getHeight() - mShapeH)));
125                 }
126             });
127             return anim;
128         }
129     }
130 }
131