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