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 }