1 /*
2  * Copyright (C) 2010 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.apis.animation;
18 
19 // Need the following import to get access to the app resources, since this
20 // class is in a sub-package.
21 import android.animation.Animator;
22 import android.animation.ObjectAnimator;
23 import com.example.android.apis.R;
24 
25 import android.animation.AnimatorListenerAdapter;
26 import android.animation.Keyframe;
27 import android.animation.LayoutTransition;
28 import android.animation.PropertyValuesHolder;
29 import android.view.View;
30 import android.view.ViewGroup;
31 import android.widget.CheckBox;
32 import android.widget.CompoundButton;
33 
34 import android.app.Activity;
35 import android.os.Bundle;
36 import android.widget.Button;
37 
38 /**
39  * This application demonstrates how to use LayoutTransition to automate transition animations
40  * as items are removed from or added to a container.
41  */
42 public class LayoutAnimations extends Activity {
43 
44     private int numButtons = 1;
45     ViewGroup container = null;
46     Animator defaultAppearingAnim, defaultDisappearingAnim;
47     Animator defaultChangingAppearingAnim, defaultChangingDisappearingAnim;
48     Animator customAppearingAnim, customDisappearingAnim;
49     Animator customChangingAppearingAnim, customChangingDisappearingAnim;
50     Animator currentAppearingAnim, currentDisappearingAnim;
51     Animator currentChangingAppearingAnim, currentChangingDisappearingAnim;
52 
53     /** Called when the activity is first created. */
54     @Override
onCreate(Bundle savedInstanceState)55     public void onCreate(Bundle savedInstanceState) {
56         super.onCreate(savedInstanceState);
57         setContentView(R.layout.layout_animations);
58 
59         container = new FixedGridLayout(this);
60         container.setClipChildren(false);
61         ((FixedGridLayout)container).setCellHeight(90);
62         ((FixedGridLayout)container).setCellWidth(100);
63         final LayoutTransition transitioner = new LayoutTransition();
64         container.setLayoutTransition(transitioner);
65         defaultAppearingAnim = transitioner.getAnimator(LayoutTransition.APPEARING);
66         defaultDisappearingAnim =
67                 transitioner.getAnimator(LayoutTransition.DISAPPEARING);
68         defaultChangingAppearingAnim =
69                 transitioner.getAnimator(LayoutTransition.CHANGE_APPEARING);
70         defaultChangingDisappearingAnim =
71                 transitioner.getAnimator(LayoutTransition.CHANGE_DISAPPEARING);
72         createCustomAnimations(transitioner);
73         currentAppearingAnim = defaultAppearingAnim;
74         currentDisappearingAnim = defaultDisappearingAnim;
75         currentChangingAppearingAnim = defaultChangingAppearingAnim;
76         currentChangingDisappearingAnim = defaultChangingDisappearingAnim;
77 
78         ViewGroup parent = (ViewGroup) findViewById(R.id.parent);
79         parent.addView(container);
80         parent.setClipChildren(false);
81         Button addButton = (Button) findViewById(R.id.addNewButton);
82         addButton.setOnClickListener(new View.OnClickListener() {
83             public void onClick(View v) {
84                 Button newButton = new Button(LayoutAnimations.this);
85                 newButton.setText(String.valueOf(numButtons++));
86                 newButton.setOnClickListener(new View.OnClickListener() {
87                     public void onClick(View v) {
88                         container.removeView(v);
89                     }
90                 });
91                 container.addView(newButton, Math.min(1, container.getChildCount()));
92             }
93         });
94 
95         CheckBox customAnimCB = (CheckBox) findViewById(R.id.customAnimCB);
96         customAnimCB.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
97             public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
98                 setupTransition(transitioner);
99             }
100         });
101 
102         // Check for disabled animations
103         CheckBox appearingCB = (CheckBox) findViewById(R.id.appearingCB);
104         appearingCB.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
105             public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
106                 setupTransition(transitioner);
107             }
108         });
109         CheckBox disappearingCB = (CheckBox) findViewById(R.id.disappearingCB);
110         disappearingCB.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
111             public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
112                 setupTransition(transitioner);
113             }
114         });
115         CheckBox changingAppearingCB = (CheckBox) findViewById(R.id.changingAppearingCB);
116         changingAppearingCB.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
117             public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
118                 setupTransition(transitioner);
119             }
120         });
121         CheckBox changingDisappearingCB = (CheckBox) findViewById(R.id.changingDisappearingCB);
122         changingDisappearingCB.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
123             public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
124                 setupTransition(transitioner);
125             }
126         });
127     }
128 
setupTransition(LayoutTransition transition)129     private void setupTransition(LayoutTransition transition) {
130         CheckBox customAnimCB = (CheckBox) findViewById(R.id.customAnimCB);
131         CheckBox appearingCB = (CheckBox) findViewById(R.id.appearingCB);
132         CheckBox disappearingCB = (CheckBox) findViewById(R.id.disappearingCB);
133         CheckBox changingAppearingCB = (CheckBox) findViewById(R.id.changingAppearingCB);
134         CheckBox changingDisappearingCB = (CheckBox) findViewById(R.id.changingDisappearingCB);
135         transition.setAnimator(LayoutTransition.APPEARING, appearingCB.isChecked() ?
136                 (customAnimCB.isChecked() ? customAppearingAnim : defaultAppearingAnim) : null);
137         transition.setAnimator(LayoutTransition.DISAPPEARING, disappearingCB.isChecked() ?
138                 (customAnimCB.isChecked() ? customDisappearingAnim : defaultDisappearingAnim) : null);
139         transition.setAnimator(LayoutTransition.CHANGE_APPEARING, changingAppearingCB.isChecked() ?
140                 (customAnimCB.isChecked() ? customChangingAppearingAnim :
141                         defaultChangingAppearingAnim) : null);
142         transition.setAnimator(LayoutTransition.CHANGE_DISAPPEARING,
143                 changingDisappearingCB.isChecked() ?
144                 (customAnimCB.isChecked() ? customChangingDisappearingAnim :
145                         defaultChangingDisappearingAnim) : null);
146     }
147 
createCustomAnimations(LayoutTransition transition)148     private void createCustomAnimations(LayoutTransition transition) {
149         // Changing while Adding
150         PropertyValuesHolder pvhLeft =
151                 PropertyValuesHolder.ofInt("left", 0, 1);
152         PropertyValuesHolder pvhTop =
153                 PropertyValuesHolder.ofInt("top", 0, 1);
154         PropertyValuesHolder pvhRight =
155                 PropertyValuesHolder.ofInt("right", 0, 1);
156         PropertyValuesHolder pvhBottom =
157                 PropertyValuesHolder.ofInt("bottom", 0, 1);
158         PropertyValuesHolder pvhScaleX =
159                 PropertyValuesHolder.ofFloat("scaleX", 1f, 0f, 1f);
160         PropertyValuesHolder pvhScaleY =
161                 PropertyValuesHolder.ofFloat("scaleY", 1f, 0f, 1f);
162         customChangingAppearingAnim = ObjectAnimator.ofPropertyValuesHolder(
163                         this, pvhLeft, pvhTop, pvhRight, pvhBottom, pvhScaleX, pvhScaleY).
164                 setDuration(transition.getDuration(LayoutTransition.CHANGE_APPEARING));
165         customChangingAppearingAnim.addListener(new AnimatorListenerAdapter() {
166             public void onAnimationEnd(Animator anim) {
167                 View view = (View) ((ObjectAnimator) anim).getTarget();
168                 view.setScaleX(1f);
169                 view.setScaleY(1f);
170             }
171         });
172 
173         // Changing while Removing
174         Keyframe kf0 = Keyframe.ofFloat(0f, 0f);
175         Keyframe kf1 = Keyframe.ofFloat(.9999f, 360f);
176         Keyframe kf2 = Keyframe.ofFloat(1f, 0f);
177         PropertyValuesHolder pvhRotation =
178                 PropertyValuesHolder.ofKeyframe("rotation", kf0, kf1, kf2);
179         customChangingDisappearingAnim = ObjectAnimator.ofPropertyValuesHolder(
180                         this, pvhLeft, pvhTop, pvhRight, pvhBottom, pvhRotation).
181                 setDuration(transition.getDuration(LayoutTransition.CHANGE_DISAPPEARING));
182         customChangingDisappearingAnim.addListener(new AnimatorListenerAdapter() {
183             public void onAnimationEnd(Animator anim) {
184                 View view = (View) ((ObjectAnimator) anim).getTarget();
185                 view.setRotation(0f);
186             }
187         });
188 
189         // Adding
190         customAppearingAnim = ObjectAnimator.ofFloat(null, "rotationY", 90f, 0f).
191                 setDuration(transition.getDuration(LayoutTransition.APPEARING));
192         customAppearingAnim.addListener(new AnimatorListenerAdapter() {
193             public void onAnimationEnd(Animator anim) {
194                 View view = (View) ((ObjectAnimator) anim).getTarget();
195                 view.setRotationY(0f);
196             }
197         });
198 
199         // Removing
200         customDisappearingAnim = ObjectAnimator.ofFloat(null, "rotationX", 0f, 90f).
201                 setDuration(transition.getDuration(LayoutTransition.DISAPPEARING));
202         customDisappearingAnim.addListener(new AnimatorListenerAdapter() {
203             public void onAnimationEnd(Animator anim) {
204                 View view = (View) ((ObjectAnimator) anim).getTarget();
205                 view.setRotationX(0f);
206             }
207         });
208 
209     }
210 }