1a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase/* 2d666cf320db4134938f72b0ffe18212997f8c8d8Chet Haase * Copyright (C) 2011 The Android Open Source Project 3a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase * 4a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase * Licensed under the Apache License, Version 2.0 (the "License"); 5a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase * you may not use this file except in compliance with the License. 6a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase * You may obtain a copy of the License at 7a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase * 8a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase * http://www.apache.org/licenses/LICENSE-2.0 9a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase * 10a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase * Unless required by applicable law or agreed to in writing, software 11a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase * distributed under the License is distributed on an "AS IS" BASIS, 12a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase * See the License for the specific language governing permissions and 14a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase * limitations under the License. 15a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase */ 16a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase 17a00f3865f55c5c9cb74510ee2b239d101230133cChet Haasepackage android.view; 18a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase 19a00f3865f55c5c9cb74510ee2b239d101230133cChet Haaseimport android.animation.Animator; 20a00f3865f55c5c9cb74510ee2b239d101230133cChet Haaseimport android.animation.ValueAnimator; 21a00f3865f55c5c9cb74510ee2b239d101230133cChet Haaseimport android.animation.TimeInterpolator; 22a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase 23a00f3865f55c5c9cb74510ee2b239d101230133cChet Haaseimport java.util.ArrayList; 24a00f3865f55c5c9cb74510ee2b239d101230133cChet Haaseimport java.util.HashMap; 25a00f3865f55c5c9cb74510ee2b239d101230133cChet Haaseimport java.util.Set; 26a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase 27a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase/** 28a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase * This class enables automatic and optimized animation of select properties on View objects. 29a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase * If only one or two properties on a View object are being animated, then using an 30a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase * {@link android.animation.ObjectAnimator} is fine; the property setters called by ObjectAnimator 31a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase * are well equipped to do the right thing to set the property and invalidate the view 32a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase * appropriately. But if several properties are animated simultaneously, or if you just want a 33a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase * more convenient syntax to animate a specific property, then ViewPropertyAnimator might be 34a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase * more well-suited to the task. 35a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase * 36d666cf320db4134938f72b0ffe18212997f8c8d8Chet Haase * <p>This class may provide better performance for several simultaneous animations, because 37d666cf320db4134938f72b0ffe18212997f8c8d8Chet Haase * it will optimize invalidate calls to take place only once for several properties instead of each 38d666cf320db4134938f72b0ffe18212997f8c8d8Chet Haase * animated property independently causing its own invalidation. Also, the syntax of using this 39a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase * class could be easier to use because the caller need only tell the View object which 40d666cf320db4134938f72b0ffe18212997f8c8d8Chet Haase * property to animate, and the value to animate either to or by, and this class handles the 41a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase * details of configuring the underlying Animator class and starting it.</p> 42a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase * 43a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase * <p>This class is not constructed by the caller, but rather by the View whose properties 44a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase * it will animate. Calls to {@link android.view.View#animate()} will return a reference 45a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase * to the appropriate ViewPropertyAnimator object for that View.</p> 46a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase * 47a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase */ 48a00f3865f55c5c9cb74510ee2b239d101230133cChet Haasepublic class ViewPropertyAnimator { 49a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase 50a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase /** 51a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase * The View whose properties are being animated by this class. This is set at 52a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase * construction time. 53a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase */ 54ddb715b238c098d8b561a44b9687f0bc67a4c141Dianne Hackborn private final View mView; 55a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase 56a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase /** 57a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase * The duration of the underlying Animator object. By default, we don't set the duration 58a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase * on the Animator and just use its default duration. If the duration is ever set on this 59a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase * Animator, then we use the duration that it was set to. 60a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase */ 61a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase private long mDuration; 62a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase 63a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase /** 64a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase * A flag indicating whether the duration has been set on this object. If not, we don't set 65a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase * the duration on the underlying Animator, but instead just use its default duration. 66a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase */ 67a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase private boolean mDurationSet = false; 68a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase 69a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase /** 708d5f808f70c1d47437eaf49234c1b3a23c244040Chet Haase * The startDelay of the underlying Animator object. By default, we don't set the startDelay 718d5f808f70c1d47437eaf49234c1b3a23c244040Chet Haase * on the Animator and just use its default startDelay. If the startDelay is ever set on this 728d5f808f70c1d47437eaf49234c1b3a23c244040Chet Haase * Animator, then we use the startDelay that it was set to. 738d5f808f70c1d47437eaf49234c1b3a23c244040Chet Haase */ 748d5f808f70c1d47437eaf49234c1b3a23c244040Chet Haase private long mStartDelay = 0; 758d5f808f70c1d47437eaf49234c1b3a23c244040Chet Haase 768d5f808f70c1d47437eaf49234c1b3a23c244040Chet Haase /** 778d5f808f70c1d47437eaf49234c1b3a23c244040Chet Haase * A flag indicating whether the startDelay has been set on this object. If not, we don't set 788d5f808f70c1d47437eaf49234c1b3a23c244040Chet Haase * the startDelay on the underlying Animator, but instead just use its default startDelay. 798d5f808f70c1d47437eaf49234c1b3a23c244040Chet Haase */ 808d5f808f70c1d47437eaf49234c1b3a23c244040Chet Haase private boolean mStartDelaySet = false; 818d5f808f70c1d47437eaf49234c1b3a23c244040Chet Haase 828d5f808f70c1d47437eaf49234c1b3a23c244040Chet Haase /** 83a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase * The interpolator of the underlying Animator object. By default, we don't set the interpolator 84a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase * on the Animator and just use its default interpolator. If the interpolator is ever set on 85a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase * this Animator, then we use the interpolator that it was set to. 86a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase */ 87a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase private TimeInterpolator mInterpolator; 88a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase 89a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase /** 90a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase * A flag indicating whether the interpolator has been set on this object. If not, we don't set 91a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase * the interpolator on the underlying Animator, but instead just use its default interpolator. 92a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase */ 93a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase private boolean mInterpolatorSet = false; 94a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase 95a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase /** 96a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase * Listener for the lifecycle events of the underlying 97a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase */ 98a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase private Animator.AnimatorListener mListener = null; 99a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase 100a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase /** 101a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase * This listener is the mechanism by which the underlying Animator causes changes to the 102a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase * properties currently being animated, as well as the cleanup after an animation is 103a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase * complete. 104a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase */ 105a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase private AnimatorEventListener mAnimatorEventListener = new AnimatorEventListener(); 106a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase 107a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase /** 108a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase * This list holds the properties that have been asked to animate. We allow the caller to 109a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase * request several animations prior to actually starting the underlying animator. This 110a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase * enables us to run one single animator to handle several properties in parallel. Each 111a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase * property is tossed onto the pending list until the animation actually starts (which is 112a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase * done by posting it onto mView), at which time the pending list is cleared and the properties 113a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase * on that list are added to the list of properties associated with that animator. 114a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase */ 115a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase ArrayList<NameValuesHolder> mPendingAnimations = new ArrayList<NameValuesHolder>(); 116c1ca665827f0c34419a55c005254c1aaa0d58b40Chet Haase private Runnable mPendingSetupAction; 117c1ca665827f0c34419a55c005254c1aaa0d58b40Chet Haase private Runnable mPendingCleanupAction; 118c1ca665827f0c34419a55c005254c1aaa0d58b40Chet Haase private Runnable mPendingOnStartAction; 119c1ca665827f0c34419a55c005254c1aaa0d58b40Chet Haase private Runnable mPendingOnEndAction; 120a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase 121a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase /** 122a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase * Constants used to associate a property being requested and the mechanism used to set 123d666cf320db4134938f72b0ffe18212997f8c8d8Chet Haase * the property (this class calls directly into View to set the properties in question). 124a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase */ 125a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase private static final int NONE = 0x0000; 126a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase private static final int TRANSLATION_X = 0x0001; 127a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase private static final int TRANSLATION_Y = 0x0002; 128a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase private static final int SCALE_X = 0x0004; 129a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase private static final int SCALE_Y = 0x0008; 130a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase private static final int ROTATION = 0x0010; 131a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase private static final int ROTATION_X = 0x0020; 132a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase private static final int ROTATION_Y = 0x0040; 133a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase private static final int X = 0x0080; 134a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase private static final int Y = 0x0100; 135a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase private static final int ALPHA = 0x0200; 136a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase 137a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase private static final int TRANSFORM_MASK = TRANSLATION_X | TRANSLATION_Y | SCALE_X | SCALE_Y | 138a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase ROTATION | ROTATION_X | ROTATION_Y | X | Y; 139a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase 140a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase /** 141a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase * The mechanism by which the user can request several properties that are then animated 142a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase * together works by posting this Runnable to start the underlying Animator. Every time 143a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase * a property animation is requested, we cancel any previous postings of the Runnable 144a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase * and re-post it. This means that we will only ever run the Runnable (and thus start the 145a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase * underlying animator) after the caller is done setting the properties that should be 146a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase * animated together. 147a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase */ 148a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase private Runnable mAnimationStarter = new Runnable() { 149a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase @Override 150a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase public void run() { 151a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase startAnimation(); 152a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase } 153a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase }; 154a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase 155a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase /** 156a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase * This class holds information about the overall animation being run on the set of 157a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase * properties. The mask describes which properties are being animated and the 158a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase * values holder is the list of all property/value objects. 159a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase */ 160a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase private static class PropertyBundle { 161a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase int mPropertyMask; 162a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase ArrayList<NameValuesHolder> mNameValuesHolder; 163ba592d200390d89723682f1a7e40d308d7804b36Chet Haase 164a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase PropertyBundle(int propertyMask, ArrayList<NameValuesHolder> nameValuesHolder) { 165a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase mPropertyMask = propertyMask; 166a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase mNameValuesHolder = nameValuesHolder; 167a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase } 168ba592d200390d89723682f1a7e40d308d7804b36Chet Haase 169ba592d200390d89723682f1a7e40d308d7804b36Chet Haase /** 170ba592d200390d89723682f1a7e40d308d7804b36Chet Haase * Removes the given property from being animated as a part of this 171ba592d200390d89723682f1a7e40d308d7804b36Chet Haase * PropertyBundle. If the property was a part of this bundle, it returns 172ba592d200390d89723682f1a7e40d308d7804b36Chet Haase * true to indicate that it was, in fact, canceled. This is an indication 173ba592d200390d89723682f1a7e40d308d7804b36Chet Haase * to the caller that a cancellation actually occurred. 174ba592d200390d89723682f1a7e40d308d7804b36Chet Haase * 175ba592d200390d89723682f1a7e40d308d7804b36Chet Haase * @param propertyConstant The property whose cancellation is requested. 176ba592d200390d89723682f1a7e40d308d7804b36Chet Haase * @return true if the given property is a part of this bundle and if it 177ba592d200390d89723682f1a7e40d308d7804b36Chet Haase * has therefore been canceled. 178ba592d200390d89723682f1a7e40d308d7804b36Chet Haase */ 179ba592d200390d89723682f1a7e40d308d7804b36Chet Haase boolean cancel(int propertyConstant) { 180ba592d200390d89723682f1a7e40d308d7804b36Chet Haase if ((mPropertyMask & propertyConstant) != 0 && mNameValuesHolder != null) { 181ba592d200390d89723682f1a7e40d308d7804b36Chet Haase int count = mNameValuesHolder.size(); 182ba592d200390d89723682f1a7e40d308d7804b36Chet Haase for (int i = 0; i < count; ++i) { 183ba592d200390d89723682f1a7e40d308d7804b36Chet Haase NameValuesHolder nameValuesHolder = mNameValuesHolder.get(i); 184ba592d200390d89723682f1a7e40d308d7804b36Chet Haase if (nameValuesHolder.mNameConstant == propertyConstant) { 185ba592d200390d89723682f1a7e40d308d7804b36Chet Haase mNameValuesHolder.remove(i); 186ba592d200390d89723682f1a7e40d308d7804b36Chet Haase mPropertyMask &= ~propertyConstant; 187ba592d200390d89723682f1a7e40d308d7804b36Chet Haase return true; 188ba592d200390d89723682f1a7e40d308d7804b36Chet Haase } 189ba592d200390d89723682f1a7e40d308d7804b36Chet Haase } 190ba592d200390d89723682f1a7e40d308d7804b36Chet Haase } 191ba592d200390d89723682f1a7e40d308d7804b36Chet Haase return false; 192ba592d200390d89723682f1a7e40d308d7804b36Chet Haase } 193a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase } 194a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase 195a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase /** 196a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase * This list tracks the list of properties being animated by any particular animator. 197a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase * In most situations, there would only ever be one animator running at a time. But it is 198a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase * possible to request some properties to animate together, then while those properties 199a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase * are animating, to request some other properties to animate together. The way that 200a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase * works is by having this map associate the group of properties being animated with the 201a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase * animator handling the animation. On every update event for an Animator, we ask the 202a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase * map for the associated properties and set them accordingly. 203a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase */ 204a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase private HashMap<Animator, PropertyBundle> mAnimatorMap = 205a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase new HashMap<Animator, PropertyBundle>(); 206c1ca665827f0c34419a55c005254c1aaa0d58b40Chet Haase private HashMap<Animator, Runnable> mAnimatorSetupMap; 207c1ca665827f0c34419a55c005254c1aaa0d58b40Chet Haase private HashMap<Animator, Runnable> mAnimatorCleanupMap; 208c1ca665827f0c34419a55c005254c1aaa0d58b40Chet Haase private HashMap<Animator, Runnable> mAnimatorOnStartMap; 209c1ca665827f0c34419a55c005254c1aaa0d58b40Chet Haase private HashMap<Animator, Runnable> mAnimatorOnEndMap; 210a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase 211a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase /** 212a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase * This is the information we need to set each property during the animation. 213a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase * mNameConstant is used to set the appropriate field in View, and the from/delta 214a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase * values are used to calculate the animated value for a given animation fraction 215a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase * during the animation. 216a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase */ 217a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase private static class NameValuesHolder { 218a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase int mNameConstant; 219a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase float mFromValue; 220a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase float mDeltaValue; 221a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase NameValuesHolder(int nameConstant, float fromValue, float deltaValue) { 222a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase mNameConstant = nameConstant; 223a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase mFromValue = fromValue; 224a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase mDeltaValue = deltaValue; 225a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase } 226a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase } 227a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase 228a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase /** 229a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase * Constructor, called by View. This is private by design, as the user should only 230a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase * get a ViewPropertyAnimator by calling View.animate(). 231a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase * 232a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase * @param view The View associated with this ViewPropertyAnimator 233a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase */ 234a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase ViewPropertyAnimator(View view) { 235a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase mView = view; 236ddb715b238c098d8b561a44b9687f0bc67a4c141Dianne Hackborn view.ensureTransformationInfo(); 237a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase } 238a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase 239a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase /** 240a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase * Sets the duration for the underlying animator that animates the requested properties. 241a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase * By default, the animator uses the default value for ValueAnimator. Calling this method 242a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase * will cause the declared value to be used instead. 243a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase * @param duration The length of ensuing property animations, in milliseconds. The value 244a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase * cannot be negative. 245a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase * @return This object, allowing calls to methods in this class to be chained. 246a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase */ 247a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase public ViewPropertyAnimator setDuration(long duration) { 248a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase if (duration < 0) { 249a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase throw new IllegalArgumentException("Animators cannot have negative duration: " + 250a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase duration); 251a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase } 252a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase mDurationSet = true; 253a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase mDuration = duration; 254a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase return this; 255a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase } 256a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase 257a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase /** 2588d5f808f70c1d47437eaf49234c1b3a23c244040Chet Haase * Returns the current duration of property animations. If the duration was set on this 2598d5f808f70c1d47437eaf49234c1b3a23c244040Chet Haase * object, that value is returned. Otherwise, the default value of the underlying Animator 2608d5f808f70c1d47437eaf49234c1b3a23c244040Chet Haase * is returned. 2618d5f808f70c1d47437eaf49234c1b3a23c244040Chet Haase * 2628d5f808f70c1d47437eaf49234c1b3a23c244040Chet Haase * @see #setDuration(long) 2638d5f808f70c1d47437eaf49234c1b3a23c244040Chet Haase * @return The duration of animations, in milliseconds. 2648d5f808f70c1d47437eaf49234c1b3a23c244040Chet Haase */ 2658d5f808f70c1d47437eaf49234c1b3a23c244040Chet Haase public long getDuration() { 266cbbd93ae701b9af2e5054d59286bdbf6275c2838Chet Haase if (mDurationSet) { 267cbbd93ae701b9af2e5054d59286bdbf6275c2838Chet Haase return mDuration; 2688d5f808f70c1d47437eaf49234c1b3a23c244040Chet Haase } else { 2698d5f808f70c1d47437eaf49234c1b3a23c244040Chet Haase // Just return the default from ValueAnimator, since that's what we'd get if 2708d5f808f70c1d47437eaf49234c1b3a23c244040Chet Haase // the value has not been set otherwise 2718d5f808f70c1d47437eaf49234c1b3a23c244040Chet Haase return new ValueAnimator().getDuration(); 2728d5f808f70c1d47437eaf49234c1b3a23c244040Chet Haase } 2738d5f808f70c1d47437eaf49234c1b3a23c244040Chet Haase } 2748d5f808f70c1d47437eaf49234c1b3a23c244040Chet Haase 2758d5f808f70c1d47437eaf49234c1b3a23c244040Chet Haase /** 2768d5f808f70c1d47437eaf49234c1b3a23c244040Chet Haase * Returns the current startDelay of property animations. If the startDelay was set on this 2778d5f808f70c1d47437eaf49234c1b3a23c244040Chet Haase * object, that value is returned. Otherwise, the default value of the underlying Animator 2788d5f808f70c1d47437eaf49234c1b3a23c244040Chet Haase * is returned. 2798d5f808f70c1d47437eaf49234c1b3a23c244040Chet Haase * 2808d5f808f70c1d47437eaf49234c1b3a23c244040Chet Haase * @see #setStartDelay(long) 2818d5f808f70c1d47437eaf49234c1b3a23c244040Chet Haase * @return The startDelay of animations, in milliseconds. 2828d5f808f70c1d47437eaf49234c1b3a23c244040Chet Haase */ 2838d5f808f70c1d47437eaf49234c1b3a23c244040Chet Haase public long getStartDelay() { 2848d5f808f70c1d47437eaf49234c1b3a23c244040Chet Haase if (mStartDelaySet) { 2858d5f808f70c1d47437eaf49234c1b3a23c244040Chet Haase return mStartDelay; 2868d5f808f70c1d47437eaf49234c1b3a23c244040Chet Haase } else { 2878d5f808f70c1d47437eaf49234c1b3a23c244040Chet Haase // Just return the default from ValueAnimator (0), since that's what we'd get if 2888d5f808f70c1d47437eaf49234c1b3a23c244040Chet Haase // the value has not been set otherwise 2898d5f808f70c1d47437eaf49234c1b3a23c244040Chet Haase return 0; 2908d5f808f70c1d47437eaf49234c1b3a23c244040Chet Haase } 2918d5f808f70c1d47437eaf49234c1b3a23c244040Chet Haase } 2928d5f808f70c1d47437eaf49234c1b3a23c244040Chet Haase 2938d5f808f70c1d47437eaf49234c1b3a23c244040Chet Haase /** 2948d5f808f70c1d47437eaf49234c1b3a23c244040Chet Haase * Sets the startDelay for the underlying animator that animates the requested properties. 2958d5f808f70c1d47437eaf49234c1b3a23c244040Chet Haase * By default, the animator uses the default value for ValueAnimator. Calling this method 2968d5f808f70c1d47437eaf49234c1b3a23c244040Chet Haase * will cause the declared value to be used instead. 2978d5f808f70c1d47437eaf49234c1b3a23c244040Chet Haase * @param startDelay The delay of ensuing property animations, in milliseconds. The value 2988d5f808f70c1d47437eaf49234c1b3a23c244040Chet Haase * cannot be negative. 2998d5f808f70c1d47437eaf49234c1b3a23c244040Chet Haase * @return This object, allowing calls to methods in this class to be chained. 3008d5f808f70c1d47437eaf49234c1b3a23c244040Chet Haase */ 3018d5f808f70c1d47437eaf49234c1b3a23c244040Chet Haase public ViewPropertyAnimator setStartDelay(long startDelay) { 3028d5f808f70c1d47437eaf49234c1b3a23c244040Chet Haase if (startDelay < 0) { 3038d5f808f70c1d47437eaf49234c1b3a23c244040Chet Haase throw new IllegalArgumentException("Animators cannot have negative duration: " + 3048d5f808f70c1d47437eaf49234c1b3a23c244040Chet Haase startDelay); 3058d5f808f70c1d47437eaf49234c1b3a23c244040Chet Haase } 3068d5f808f70c1d47437eaf49234c1b3a23c244040Chet Haase mStartDelaySet = true; 3078d5f808f70c1d47437eaf49234c1b3a23c244040Chet Haase mStartDelay = startDelay; 3088d5f808f70c1d47437eaf49234c1b3a23c244040Chet Haase return this; 3098d5f808f70c1d47437eaf49234c1b3a23c244040Chet Haase } 3108d5f808f70c1d47437eaf49234c1b3a23c244040Chet Haase 3118d5f808f70c1d47437eaf49234c1b3a23c244040Chet Haase /** 312a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase * Sets the interpolator for the underlying animator that animates the requested properties. 313a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase * By default, the animator uses the default interpolator for ValueAnimator. Calling this method 314a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase * will cause the declared object to be used instead. 315a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase * 316a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase * @param interpolator The TimeInterpolator to be used for ensuing property animations. 317a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase * @return This object, allowing calls to methods in this class to be chained. 318a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase */ 319a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase public ViewPropertyAnimator setInterpolator(TimeInterpolator interpolator) { 320a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase mInterpolatorSet = true; 321a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase mInterpolator = interpolator; 322a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase return this; 323a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase } 324a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase 325a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase /** 326a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase * Sets a listener for events in the underlying Animators that run the property 327a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase * animations. 328a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase * 329a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase * @param listener The listener to be called with AnimatorListener events. 330a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase * @return This object, allowing calls to methods in this class to be chained. 331a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase */ 332a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase public ViewPropertyAnimator setListener(Animator.AnimatorListener listener) { 333a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase mListener = listener; 334a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase return this; 335a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase } 336a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase 337a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase /** 3388d5f808f70c1d47437eaf49234c1b3a23c244040Chet Haase * Starts the currently pending property animations immediately. Calling <code>start()</code> 3398d5f808f70c1d47437eaf49234c1b3a23c244040Chet Haase * is optional because all animations start automatically at the next opportunity. However, 3408d5f808f70c1d47437eaf49234c1b3a23c244040Chet Haase * if the animations are needed to start immediately and synchronously (not at the time when 3418d5f808f70c1d47437eaf49234c1b3a23c244040Chet Haase * the next event is processed by the hierarchy, which is when the animations would begin 3428d5f808f70c1d47437eaf49234c1b3a23c244040Chet Haase * otherwise), then this method can be used. 3438d5f808f70c1d47437eaf49234c1b3a23c244040Chet Haase */ 3448d5f808f70c1d47437eaf49234c1b3a23c244040Chet Haase public void start() { 345500998d401e1c936bf60facecd5e9699d2eadb66Michael Jurka mView.removeCallbacks(mAnimationStarter); 3468d5f808f70c1d47437eaf49234c1b3a23c244040Chet Haase startAnimation(); 3478d5f808f70c1d47437eaf49234c1b3a23c244040Chet Haase } 3488d5f808f70c1d47437eaf49234c1b3a23c244040Chet Haase 3498d5f808f70c1d47437eaf49234c1b3a23c244040Chet Haase /** 3508d5f808f70c1d47437eaf49234c1b3a23c244040Chet Haase * Cancels all property animations that are currently running or pending. 3518d5f808f70c1d47437eaf49234c1b3a23c244040Chet Haase */ 3528d5f808f70c1d47437eaf49234c1b3a23c244040Chet Haase public void cancel() { 3538d5f808f70c1d47437eaf49234c1b3a23c244040Chet Haase if (mAnimatorMap.size() > 0) { 3548d5f808f70c1d47437eaf49234c1b3a23c244040Chet Haase HashMap<Animator, PropertyBundle> mAnimatorMapCopy = 3558d5f808f70c1d47437eaf49234c1b3a23c244040Chet Haase (HashMap<Animator, PropertyBundle>)mAnimatorMap.clone(); 3568d5f808f70c1d47437eaf49234c1b3a23c244040Chet Haase Set<Animator> animatorSet = mAnimatorMapCopy.keySet(); 3578d5f808f70c1d47437eaf49234c1b3a23c244040Chet Haase for (Animator runningAnim : animatorSet) { 3588d5f808f70c1d47437eaf49234c1b3a23c244040Chet Haase runningAnim.cancel(); 3598d5f808f70c1d47437eaf49234c1b3a23c244040Chet Haase } 3608d5f808f70c1d47437eaf49234c1b3a23c244040Chet Haase } 3618d5f808f70c1d47437eaf49234c1b3a23c244040Chet Haase mPendingAnimations.clear(); 3623a000a52d6863bd1c6c9822a9cfd83e00f3aaf79Chet Haase mView.removeCallbacks(mAnimationStarter); 3638d5f808f70c1d47437eaf49234c1b3a23c244040Chet Haase } 3648d5f808f70c1d47437eaf49234c1b3a23c244040Chet Haase 3658d5f808f70c1d47437eaf49234c1b3a23c244040Chet Haase /** 366a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase * This method will cause the View's <code>x</code> property to be animated to the 367d666cf320db4134938f72b0ffe18212997f8c8d8Chet Haase * specified value. Animations already running on the property will be canceled. 368a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase * 369a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase * @param value The value to be animated to. 370a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase * @see View#setX(float) 371a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase * @return This object, allowing calls to methods in this class to be chained. 372a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase */ 373a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase public ViewPropertyAnimator x(float value) { 374a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase animateProperty(X, value); 375a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase return this; 376a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase } 377a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase 378a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase /** 379a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase * This method will cause the View's <code>x</code> property to be animated by the 380d666cf320db4134938f72b0ffe18212997f8c8d8Chet Haase * specified value. Animations already running on the property will be canceled. 381a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase * 382a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase * @param value The amount to be animated by, as an offset from the current value. 383a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase * @see View#setX(float) 384a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase * @return This object, allowing calls to methods in this class to be chained. 385a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase */ 386a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase public ViewPropertyAnimator xBy(float value) { 387a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase animatePropertyBy(X, value); 388a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase return this; 389a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase } 390a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase 391a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase /** 392a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase * This method will cause the View's <code>y</code> property to be animated to the 393d666cf320db4134938f72b0ffe18212997f8c8d8Chet Haase * specified value. Animations already running on the property will be canceled. 394a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase * 395a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase * @param value The value to be animated to. 396a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase * @see View#setY(float) 397a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase * @return This object, allowing calls to methods in this class to be chained. 398a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase */ 399a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase public ViewPropertyAnimator y(float value) { 400a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase animateProperty(Y, value); 401a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase return this; 402a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase } 403a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase 404a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase /** 405a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase * This method will cause the View's <code>y</code> property to be animated by the 406d666cf320db4134938f72b0ffe18212997f8c8d8Chet Haase * specified value. Animations already running on the property will be canceled. 407a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase * 408a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase * @param value The amount to be animated by, as an offset from the current value. 409a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase * @see View#setY(float) 410a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase * @return This object, allowing calls to methods in this class to be chained. 411a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase */ 412a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase public ViewPropertyAnimator yBy(float value) { 413a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase animatePropertyBy(Y, value); 414a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase return this; 415a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase } 416a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase 417a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase /** 418a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase * This method will cause the View's <code>rotation</code> property to be animated to the 419d666cf320db4134938f72b0ffe18212997f8c8d8Chet Haase * specified value. Animations already running on the property will be canceled. 420a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase * 421a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase * @param value The value to be animated to. 422a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase * @see View#setRotation(float) 423a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase * @return This object, allowing calls to methods in this class to be chained. 424a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase */ 425a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase public ViewPropertyAnimator rotation(float value) { 426a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase animateProperty(ROTATION, value); 427a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase return this; 428a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase } 429a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase 430a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase /** 431a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase * This method will cause the View's <code>rotation</code> property to be animated by the 432d666cf320db4134938f72b0ffe18212997f8c8d8Chet Haase * specified value. Animations already running on the property will be canceled. 433a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase * 434a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase * @param value The amount to be animated by, as an offset from the current value. 435a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase * @see View#setRotation(float) 436a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase * @return This object, allowing calls to methods in this class to be chained. 437a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase */ 438a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase public ViewPropertyAnimator rotationBy(float value) { 439a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase animatePropertyBy(ROTATION, value); 440a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase return this; 441a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase } 442a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase 443a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase /** 444a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase * This method will cause the View's <code>rotationX</code> property to be animated to the 445d666cf320db4134938f72b0ffe18212997f8c8d8Chet Haase * specified value. Animations already running on the property will be canceled. 446a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase * 447a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase * @param value The value to be animated to. 448a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase * @see View#setRotationX(float) 449a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase * @return This object, allowing calls to methods in this class to be chained. 450a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase */ 451a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase public ViewPropertyAnimator rotationX(float value) { 452a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase animateProperty(ROTATION_X, value); 453a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase return this; 454a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase } 455a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase 456a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase /** 457a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase * This method will cause the View's <code>rotationX</code> property to be animated by the 458d666cf320db4134938f72b0ffe18212997f8c8d8Chet Haase * specified value. Animations already running on the property will be canceled. 459a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase * 460a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase * @param value The amount to be animated by, as an offset from the current value. 461a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase * @see View#setRotationX(float) 462a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase * @return This object, allowing calls to methods in this class to be chained. 463a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase */ 464a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase public ViewPropertyAnimator rotationXBy(float value) { 465a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase animatePropertyBy(ROTATION_X, value); 466a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase return this; 467a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase } 468a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase 469a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase /** 470a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase * This method will cause the View's <code>rotationY</code> property to be animated to the 471d666cf320db4134938f72b0ffe18212997f8c8d8Chet Haase * specified value. Animations already running on the property will be canceled. 472a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase * 473a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase * @param value The value to be animated to. 474a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase * @see View#setRotationY(float) 475a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase * @return This object, allowing calls to methods in this class to be chained. 476a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase */ 477a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase public ViewPropertyAnimator rotationY(float value) { 478a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase animateProperty(ROTATION_Y, value); 479a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase return this; 480a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase } 481a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase 482a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase /** 483a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase * This method will cause the View's <code>rotationY</code> property to be animated by the 484d666cf320db4134938f72b0ffe18212997f8c8d8Chet Haase * specified value. Animations already running on the property will be canceled. 485a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase * 486a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase * @param value The amount to be animated by, as an offset from the current value. 487a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase * @see View#setRotationY(float) 488a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase * @return This object, allowing calls to methods in this class to be chained. 489a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase */ 490a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase public ViewPropertyAnimator rotationYBy(float value) { 491a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase animatePropertyBy(ROTATION_Y, value); 492a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase return this; 493a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase } 494a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase 495a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase /** 496a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase * This method will cause the View's <code>translationX</code> property to be animated to the 497d666cf320db4134938f72b0ffe18212997f8c8d8Chet Haase * specified value. Animations already running on the property will be canceled. 498a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase * 499a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase * @param value The value to be animated to. 500a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase * @see View#setTranslationX(float) 501a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase * @return This object, allowing calls to methods in this class to be chained. 502a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase */ 503a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase public ViewPropertyAnimator translationX(float value) { 504a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase animateProperty(TRANSLATION_X, value); 505a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase return this; 506a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase } 507a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase 508a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase /** 509a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase * This method will cause the View's <code>translationX</code> property to be animated by the 510d666cf320db4134938f72b0ffe18212997f8c8d8Chet Haase * specified value. Animations already running on the property will be canceled. 511a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase * 512a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase * @param value The amount to be animated by, as an offset from the current value. 513a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase * @see View#setTranslationX(float) 514a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase * @return This object, allowing calls to methods in this class to be chained. 515a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase */ 516a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase public ViewPropertyAnimator translationXBy(float value) { 517a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase animatePropertyBy(TRANSLATION_X, value); 518a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase return this; 519a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase } 520a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase 521a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase /** 522a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase * This method will cause the View's <code>translationY</code> property to be animated to the 523d666cf320db4134938f72b0ffe18212997f8c8d8Chet Haase * specified value. Animations already running on the property will be canceled. 524a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase * 525a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase * @param value The value to be animated to. 526a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase * @see View#setTranslationY(float) 527a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase * @return This object, allowing calls to methods in this class to be chained. 528a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase */ 529a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase public ViewPropertyAnimator translationY(float value) { 530a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase animateProperty(TRANSLATION_Y, value); 531a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase return this; 532a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase } 533a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase 534a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase /** 535a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase * This method will cause the View's <code>translationY</code> property to be animated by the 536d666cf320db4134938f72b0ffe18212997f8c8d8Chet Haase * specified value. Animations already running on the property will be canceled. 537a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase * 538a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase * @param value The amount to be animated by, as an offset from the current value. 539a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase * @see View#setTranslationY(float) 540a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase * @return This object, allowing calls to methods in this class to be chained. 541a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase */ 542a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase public ViewPropertyAnimator translationYBy(float value) { 543a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase animatePropertyBy(TRANSLATION_Y, value); 544a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase return this; 545a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase } 546a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase 547a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase /** 548a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase * This method will cause the View's <code>scaleX</code> property to be animated to the 549d666cf320db4134938f72b0ffe18212997f8c8d8Chet Haase * specified value. Animations already running on the property will be canceled. 550a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase * 551a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase * @param value The value to be animated to. 552a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase * @see View#setScaleX(float) 553a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase * @return This object, allowing calls to methods in this class to be chained. 554a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase */ 555a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase public ViewPropertyAnimator scaleX(float value) { 556a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase animateProperty(SCALE_X, value); 557a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase return this; 558a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase } 559a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase 560a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase /** 561a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase * This method will cause the View's <code>scaleX</code> property to be animated by the 562d666cf320db4134938f72b0ffe18212997f8c8d8Chet Haase * specified value. Animations already running on the property will be canceled. 563a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase * 564a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase * @param value The amount to be animated by, as an offset from the current value. 565a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase * @see View#setScaleX(float) 566a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase * @return This object, allowing calls to methods in this class to be chained. 567a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase */ 568a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase public ViewPropertyAnimator scaleXBy(float value) { 569a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase animatePropertyBy(SCALE_X, value); 570a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase return this; 571a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase } 572a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase 573a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase /** 574a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase * This method will cause the View's <code>scaleY</code> property to be animated to the 575d666cf320db4134938f72b0ffe18212997f8c8d8Chet Haase * specified value. Animations already running on the property will be canceled. 576a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase * 577a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase * @param value The value to be animated to. 578a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase * @see View#setScaleY(float) 579a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase * @return This object, allowing calls to methods in this class to be chained. 580a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase */ 581a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase public ViewPropertyAnimator scaleY(float value) { 582a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase animateProperty(SCALE_Y, value); 583a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase return this; 584a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase } 585a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase 586a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase /** 587a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase * This method will cause the View's <code>scaleY</code> property to be animated by the 588d666cf320db4134938f72b0ffe18212997f8c8d8Chet Haase * specified value. Animations already running on the property will be canceled. 589a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase * 590a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase * @param value The amount to be animated by, as an offset from the current value. 591a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase * @see View#setScaleY(float) 592a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase * @return This object, allowing calls to methods in this class to be chained. 593a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase */ 594a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase public ViewPropertyAnimator scaleYBy(float value) { 595a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase animatePropertyBy(SCALE_Y, value); 596a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase return this; 597a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase } 598a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase 599a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase /** 600a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase * This method will cause the View's <code>alpha</code> property to be animated to the 601d666cf320db4134938f72b0ffe18212997f8c8d8Chet Haase * specified value. Animations already running on the property will be canceled. 602a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase * 603a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase * @param value The value to be animated to. 604a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase * @see View#setAlpha(float) 605a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase * @return This object, allowing calls to methods in this class to be chained. 606a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase */ 607a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase public ViewPropertyAnimator alpha(float value) { 608a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase animateProperty(ALPHA, value); 609a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase return this; 610a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase } 611a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase 612a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase /** 613a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase * This method will cause the View's <code>alpha</code> property to be animated by the 614d666cf320db4134938f72b0ffe18212997f8c8d8Chet Haase * specified value. Animations already running on the property will be canceled. 615a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase * 616a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase * @param value The amount to be animated by, as an offset from the current value. 617a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase * @see View#setAlpha(float) 618a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase * @return This object, allowing calls to methods in this class to be chained. 619a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase */ 620a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase public ViewPropertyAnimator alphaBy(float value) { 621a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase animatePropertyBy(ALPHA, value); 622a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase return this; 623a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase } 624a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase 625a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase /** 626c1ca665827f0c34419a55c005254c1aaa0d58b40Chet Haase * The View associated with this ViewPropertyAnimator will have its 627c1ca665827f0c34419a55c005254c1aaa0d58b40Chet Haase * {@link View#setLayerType(int, android.graphics.Paint) layer type} set to 628cb150fe9e6495256019b02be51e736679b57c1b5Chet Haase * {@link View#LAYER_TYPE_HARDWARE} for the duration of the next animation. 629cb150fe9e6495256019b02be51e736679b57c1b5Chet Haase * As stated in the documentation for {@link View#LAYER_TYPE_HARDWARE}, 630cb150fe9e6495256019b02be51e736679b57c1b5Chet Haase * the actual type of layer used internally depends on the runtime situation of the 631cb150fe9e6495256019b02be51e736679b57c1b5Chet Haase * view. If the activity and this view are hardware-accelerated, then the layer will be 632cb150fe9e6495256019b02be51e736679b57c1b5Chet Haase * accelerated as well. If the activity or the view is not accelerated, then the layer will 633cb150fe9e6495256019b02be51e736679b57c1b5Chet Haase * effectively be the same as {@link View#LAYER_TYPE_SOFTWARE}. 634cb150fe9e6495256019b02be51e736679b57c1b5Chet Haase * 635cb150fe9e6495256019b02be51e736679b57c1b5Chet Haase * <p>This state is not persistent, either on the View or on this ViewPropertyAnimator: the 636cb150fe9e6495256019b02be51e736679b57c1b5Chet Haase * layer type of the View will be restored when the animation ends to what it was when this 637cb150fe9e6495256019b02be51e736679b57c1b5Chet Haase * method was called, and this setting on ViewPropertyAnimator is only valid for the next 638cb150fe9e6495256019b02be51e736679b57c1b5Chet Haase * animation. Note that calling this method and then independently setting the layer type of 639cb150fe9e6495256019b02be51e736679b57c1b5Chet Haase * the View (by a direct call to {@link View#setLayerType(int, android.graphics.Paint)}) will 640cb150fe9e6495256019b02be51e736679b57c1b5Chet Haase * result in some inconsistency, including having the layer type restored to its pre-withLayer() 641cb150fe9e6495256019b02be51e736679b57c1b5Chet Haase * value when the animation ends.</p> 642c1ca665827f0c34419a55c005254c1aaa0d58b40Chet Haase * 643c1ca665827f0c34419a55c005254c1aaa0d58b40Chet Haase * @see View#setLayerType(int, android.graphics.Paint) 644c1ca665827f0c34419a55c005254c1aaa0d58b40Chet Haase * @return This object, allowing calls to methods in this class to be chained. 645c1ca665827f0c34419a55c005254c1aaa0d58b40Chet Haase */ 646c1ca665827f0c34419a55c005254c1aaa0d58b40Chet Haase public ViewPropertyAnimator withLayer() { 647c1ca665827f0c34419a55c005254c1aaa0d58b40Chet Haase mPendingSetupAction= new Runnable() { 648c1ca665827f0c34419a55c005254c1aaa0d58b40Chet Haase @Override 649c1ca665827f0c34419a55c005254c1aaa0d58b40Chet Haase public void run() { 650c1ca665827f0c34419a55c005254c1aaa0d58b40Chet Haase mView.setLayerType(View.LAYER_TYPE_HARDWARE, null); 651c1ca665827f0c34419a55c005254c1aaa0d58b40Chet Haase } 652c1ca665827f0c34419a55c005254c1aaa0d58b40Chet Haase }; 653c1ca665827f0c34419a55c005254c1aaa0d58b40Chet Haase final int currentLayerType = mView.getLayerType(); 654c1ca665827f0c34419a55c005254c1aaa0d58b40Chet Haase mPendingCleanupAction = new Runnable() { 655c1ca665827f0c34419a55c005254c1aaa0d58b40Chet Haase @Override 656c1ca665827f0c34419a55c005254c1aaa0d58b40Chet Haase public void run() { 657c1ca665827f0c34419a55c005254c1aaa0d58b40Chet Haase mView.setLayerType(currentLayerType, null); 658c1ca665827f0c34419a55c005254c1aaa0d58b40Chet Haase } 659c1ca665827f0c34419a55c005254c1aaa0d58b40Chet Haase }; 660c1ca665827f0c34419a55c005254c1aaa0d58b40Chet Haase if (mAnimatorSetupMap == null) { 661c1ca665827f0c34419a55c005254c1aaa0d58b40Chet Haase mAnimatorSetupMap = new HashMap<Animator, Runnable>(); 662c1ca665827f0c34419a55c005254c1aaa0d58b40Chet Haase } 663c1ca665827f0c34419a55c005254c1aaa0d58b40Chet Haase if (mAnimatorCleanupMap == null) { 664c1ca665827f0c34419a55c005254c1aaa0d58b40Chet Haase mAnimatorCleanupMap = new HashMap<Animator, Runnable>(); 665c1ca665827f0c34419a55c005254c1aaa0d58b40Chet Haase } 666c1ca665827f0c34419a55c005254c1aaa0d58b40Chet Haase 667c1ca665827f0c34419a55c005254c1aaa0d58b40Chet Haase return this; 668c1ca665827f0c34419a55c005254c1aaa0d58b40Chet Haase } 669c1ca665827f0c34419a55c005254c1aaa0d58b40Chet Haase 670c1ca665827f0c34419a55c005254c1aaa0d58b40Chet Haase /** 671c1ca665827f0c34419a55c005254c1aaa0d58b40Chet Haase * Specifies an action to take place when the next animation runs. If there is a 672c1ca665827f0c34419a55c005254c1aaa0d58b40Chet Haase * {@link #setStartDelay(long) startDelay} set on this ViewPropertyAnimator, then the 673c1ca665827f0c34419a55c005254c1aaa0d58b40Chet Haase * action will run after that startDelay expires, when the actual animation begins. 674c1ca665827f0c34419a55c005254c1aaa0d58b40Chet Haase * This method, along with {@link #withEndAction(Runnable)}, is intended to help facilitate 675c1ca665827f0c34419a55c005254c1aaa0d58b40Chet Haase * choreographing ViewPropertyAnimator animations with other animations or actions 676c1ca665827f0c34419a55c005254c1aaa0d58b40Chet Haase * in the application. 677c1ca665827f0c34419a55c005254c1aaa0d58b40Chet Haase * 678c1ca665827f0c34419a55c005254c1aaa0d58b40Chet Haase * @param runnable The action to run when the next animation starts. 679c1ca665827f0c34419a55c005254c1aaa0d58b40Chet Haase * @return This object, allowing calls to methods in this class to be chained. 680c1ca665827f0c34419a55c005254c1aaa0d58b40Chet Haase */ 681c1ca665827f0c34419a55c005254c1aaa0d58b40Chet Haase public ViewPropertyAnimator withStartAction(Runnable runnable) { 682c1ca665827f0c34419a55c005254c1aaa0d58b40Chet Haase mPendingOnStartAction = runnable; 683c1ca665827f0c34419a55c005254c1aaa0d58b40Chet Haase if (runnable != null && mAnimatorOnStartMap == null) { 684c1ca665827f0c34419a55c005254c1aaa0d58b40Chet Haase mAnimatorOnStartMap = new HashMap<Animator, Runnable>(); 685c1ca665827f0c34419a55c005254c1aaa0d58b40Chet Haase } 686c1ca665827f0c34419a55c005254c1aaa0d58b40Chet Haase return this; 687c1ca665827f0c34419a55c005254c1aaa0d58b40Chet Haase } 688c1ca665827f0c34419a55c005254c1aaa0d58b40Chet Haase 689c1ca665827f0c34419a55c005254c1aaa0d58b40Chet Haase /** 690c1ca665827f0c34419a55c005254c1aaa0d58b40Chet Haase * Specifies an action to take place when the next animation ends. The action is only 691c1ca665827f0c34419a55c005254c1aaa0d58b40Chet Haase * run if the animation ends normally; if the ViewPropertyAnimator is canceled during 692c1ca665827f0c34419a55c005254c1aaa0d58b40Chet Haase * that animation, the runnable will not run. 693c1ca665827f0c34419a55c005254c1aaa0d58b40Chet Haase * This method, along with {@link #withStartAction(Runnable)}, is intended to help facilitate 694c1ca665827f0c34419a55c005254c1aaa0d58b40Chet Haase * choreographing ViewPropertyAnimator animations with other animations or actions 695c1ca665827f0c34419a55c005254c1aaa0d58b40Chet Haase * in the application. 696c1ca665827f0c34419a55c005254c1aaa0d58b40Chet Haase * 697c1ca665827f0c34419a55c005254c1aaa0d58b40Chet Haase * <p>For example, the following code animates a view to x=200 and then back to 0:</p> 698c1ca665827f0c34419a55c005254c1aaa0d58b40Chet Haase * <pre> 699c1ca665827f0c34419a55c005254c1aaa0d58b40Chet Haase * Runnable endAction = new Runnable() { 700c1ca665827f0c34419a55c005254c1aaa0d58b40Chet Haase * public void run() { 701c1ca665827f0c34419a55c005254c1aaa0d58b40Chet Haase * view.animate().x(0); 702c1ca665827f0c34419a55c005254c1aaa0d58b40Chet Haase * } 703c1ca665827f0c34419a55c005254c1aaa0d58b40Chet Haase * }; 704c1ca665827f0c34419a55c005254c1aaa0d58b40Chet Haase * view.animate().x(200).onEnd(endAction); 705c1ca665827f0c34419a55c005254c1aaa0d58b40Chet Haase * </pre> 706c1ca665827f0c34419a55c005254c1aaa0d58b40Chet Haase * 707c1ca665827f0c34419a55c005254c1aaa0d58b40Chet Haase * @param runnable The action to run when the next animation ends. 708c1ca665827f0c34419a55c005254c1aaa0d58b40Chet Haase * @return This object, allowing calls to methods in this class to be chained. 709c1ca665827f0c34419a55c005254c1aaa0d58b40Chet Haase */ 710c1ca665827f0c34419a55c005254c1aaa0d58b40Chet Haase public ViewPropertyAnimator withEndAction(Runnable runnable) { 711c1ca665827f0c34419a55c005254c1aaa0d58b40Chet Haase mPendingOnEndAction = runnable; 712c1ca665827f0c34419a55c005254c1aaa0d58b40Chet Haase if (runnable != null && mAnimatorOnEndMap == null) { 713c1ca665827f0c34419a55c005254c1aaa0d58b40Chet Haase mAnimatorOnEndMap = new HashMap<Animator, Runnable>(); 714c1ca665827f0c34419a55c005254c1aaa0d58b40Chet Haase } 715c1ca665827f0c34419a55c005254c1aaa0d58b40Chet Haase return this; 716c1ca665827f0c34419a55c005254c1aaa0d58b40Chet Haase } 717c1ca665827f0c34419a55c005254c1aaa0d58b40Chet Haase 718c1ca665827f0c34419a55c005254c1aaa0d58b40Chet Haase /** 719a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase * Starts the underlying Animator for a set of properties. We use a single animator that 720a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase * simply runs from 0 to 1, and then use that fractional value to set each property 721a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase * value accordingly. 722a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase */ 723a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase private void startAnimation() { 724563d4f2d461d264457b7e7068e2fc7b9b0bcafb3Chet Haase mView.setHasTransientState(true); 725a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase ValueAnimator animator = ValueAnimator.ofFloat(1.0f); 726a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase ArrayList<NameValuesHolder> nameValueList = 727a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase (ArrayList<NameValuesHolder>) mPendingAnimations.clone(); 728a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase mPendingAnimations.clear(); 729a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase int propertyMask = 0; 730a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase int propertyCount = nameValueList.size(); 731a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase for (int i = 0; i < propertyCount; ++i) { 732a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase NameValuesHolder nameValuesHolder = nameValueList.get(i); 733a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase propertyMask |= nameValuesHolder.mNameConstant; 734a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase } 735a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase mAnimatorMap.put(animator, new PropertyBundle(propertyMask, nameValueList)); 736c1ca665827f0c34419a55c005254c1aaa0d58b40Chet Haase if (mPendingSetupAction != null) { 737c1ca665827f0c34419a55c005254c1aaa0d58b40Chet Haase mAnimatorSetupMap.put(animator, mPendingSetupAction); 738c1ca665827f0c34419a55c005254c1aaa0d58b40Chet Haase mPendingSetupAction = null; 739c1ca665827f0c34419a55c005254c1aaa0d58b40Chet Haase } 740c1ca665827f0c34419a55c005254c1aaa0d58b40Chet Haase if (mPendingCleanupAction != null) { 741c1ca665827f0c34419a55c005254c1aaa0d58b40Chet Haase mAnimatorCleanupMap.put(animator, mPendingCleanupAction); 742c1ca665827f0c34419a55c005254c1aaa0d58b40Chet Haase mPendingCleanupAction = null; 743c1ca665827f0c34419a55c005254c1aaa0d58b40Chet Haase } 744c1ca665827f0c34419a55c005254c1aaa0d58b40Chet Haase if (mPendingOnStartAction != null) { 745c1ca665827f0c34419a55c005254c1aaa0d58b40Chet Haase mAnimatorOnStartMap.put(animator, mPendingOnStartAction); 746c1ca665827f0c34419a55c005254c1aaa0d58b40Chet Haase mPendingOnStartAction = null; 747c1ca665827f0c34419a55c005254c1aaa0d58b40Chet Haase } 748c1ca665827f0c34419a55c005254c1aaa0d58b40Chet Haase if (mPendingOnEndAction != null) { 749c1ca665827f0c34419a55c005254c1aaa0d58b40Chet Haase mAnimatorOnEndMap.put(animator, mPendingOnEndAction); 750c1ca665827f0c34419a55c005254c1aaa0d58b40Chet Haase mPendingOnEndAction = null; 751c1ca665827f0c34419a55c005254c1aaa0d58b40Chet Haase } 752a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase animator.addUpdateListener(mAnimatorEventListener); 753a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase animator.addListener(mAnimatorEventListener); 754cbbd93ae701b9af2e5054d59286bdbf6275c2838Chet Haase if (mStartDelaySet) { 755cbbd93ae701b9af2e5054d59286bdbf6275c2838Chet Haase animator.setStartDelay(mStartDelay); 756cbbd93ae701b9af2e5054d59286bdbf6275c2838Chet Haase } 757a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase if (mDurationSet) { 758a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase animator.setDuration(mDuration); 759a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase } 760a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase if (mInterpolatorSet) { 761a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase animator.setInterpolator(mInterpolator); 762a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase } 763a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase animator.start(); 764a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase } 765a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase 766a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase /** 767a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase * Utility function, called by the various x(), y(), etc. methods. This stores the 768d666cf320db4134938f72b0ffe18212997f8c8d8Chet Haase * constant name for the property along with the from/delta values that will be used to 769a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase * calculate and set the property during the animation. This structure is added to the 770a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase * pending animations, awaiting the eventual start() of the underlying animator. A 771a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase * Runnable is posted to start the animation, and any pending such Runnable is canceled 772a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase * (which enables us to end up starting just one animator for all of the properties 773a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase * specified at one time). 774a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase * 775a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase * @param constantName The specifier for the property being animated 776a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase * @param toValue The value to which the property will animate 777a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase */ 778a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase private void animateProperty(int constantName, float toValue) { 779a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase float fromValue = getValue(constantName); 780a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase float deltaValue = toValue - fromValue; 781a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase animatePropertyBy(constantName, fromValue, deltaValue); 782a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase } 783a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase 784a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase /** 785a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase * Utility function, called by the various xBy(), yBy(), etc. methods. This method is 786a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase * just like animateProperty(), except the value is an offset from the property's 787a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase * current value, instead of an absolute "to" value. 788a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase * 789a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase * @param constantName The specifier for the property being animated 790a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase * @param byValue The amount by which the property will change 791a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase */ 792a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase private void animatePropertyBy(int constantName, float byValue) { 793a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase float fromValue = getValue(constantName); 794a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase animatePropertyBy(constantName, fromValue, byValue); 795a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase } 796a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase 797a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase /** 798d666cf320db4134938f72b0ffe18212997f8c8d8Chet Haase * Utility function, called by animateProperty() and animatePropertyBy(), which handles the 799a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase * details of adding a pending animation and posting the request to start the animation. 800a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase * 801a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase * @param constantName The specifier for the property being animated 802d666cf320db4134938f72b0ffe18212997f8c8d8Chet Haase * @param startValue The starting value of the property 803a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase * @param byValue The amount by which the property will change 804a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase */ 805d666cf320db4134938f72b0ffe18212997f8c8d8Chet Haase private void animatePropertyBy(int constantName, float startValue, float byValue) { 806ba592d200390d89723682f1a7e40d308d7804b36Chet Haase // First, cancel any existing animations on this property 807ba592d200390d89723682f1a7e40d308d7804b36Chet Haase if (mAnimatorMap.size() > 0) { 808ba592d200390d89723682f1a7e40d308d7804b36Chet Haase Animator animatorToCancel = null; 809ba592d200390d89723682f1a7e40d308d7804b36Chet Haase Set<Animator> animatorSet = mAnimatorMap.keySet(); 810ba592d200390d89723682f1a7e40d308d7804b36Chet Haase for (Animator runningAnim : animatorSet) { 811ba592d200390d89723682f1a7e40d308d7804b36Chet Haase PropertyBundle bundle = mAnimatorMap.get(runningAnim); 812ba592d200390d89723682f1a7e40d308d7804b36Chet Haase if (bundle.cancel(constantName)) { 813ba592d200390d89723682f1a7e40d308d7804b36Chet Haase // property was canceled - cancel the animation if it's now empty 814ba592d200390d89723682f1a7e40d308d7804b36Chet Haase // Note that it's safe to break out here because every new animation 815ba592d200390d89723682f1a7e40d308d7804b36Chet Haase // on a property will cancel a previous animation on that property, so 816ba592d200390d89723682f1a7e40d308d7804b36Chet Haase // there can only ever be one such animation running. 817ba592d200390d89723682f1a7e40d308d7804b36Chet Haase if (bundle.mPropertyMask == NONE) { 8188d5f808f70c1d47437eaf49234c1b3a23c244040Chet Haase // the animation is no longer changing anything - cancel it 819ba592d200390d89723682f1a7e40d308d7804b36Chet Haase animatorToCancel = runningAnim; 820ba592d200390d89723682f1a7e40d308d7804b36Chet Haase break; 821ba592d200390d89723682f1a7e40d308d7804b36Chet Haase } 822ba592d200390d89723682f1a7e40d308d7804b36Chet Haase } 823ba592d200390d89723682f1a7e40d308d7804b36Chet Haase } 824ba592d200390d89723682f1a7e40d308d7804b36Chet Haase if (animatorToCancel != null) { 825ba592d200390d89723682f1a7e40d308d7804b36Chet Haase animatorToCancel.cancel(); 826ba592d200390d89723682f1a7e40d308d7804b36Chet Haase } 827ba592d200390d89723682f1a7e40d308d7804b36Chet Haase } 828ba592d200390d89723682f1a7e40d308d7804b36Chet Haase 829a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase NameValuesHolder nameValuePair = new NameValuesHolder(constantName, startValue, byValue); 830a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase mPendingAnimations.add(nameValuePair); 8313a000a52d6863bd1c6c9822a9cfd83e00f3aaf79Chet Haase mView.removeCallbacks(mAnimationStarter); 832a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase mView.post(mAnimationStarter); 833a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase } 834a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase 835a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase /** 836a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase * This method handles setting the property values directly in the View object's fields. 837a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase * propertyConstant tells it which property should be set, value is the value to set 838a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase * the property to. 839a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase * 840a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase * @param propertyConstant The property to be set 841a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase * @param value The value to set the property to 842a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase */ 843a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase private void setValue(int propertyConstant, float value) { 844ddb715b238c098d8b561a44b9687f0bc67a4c141Dianne Hackborn final View.TransformationInfo info = mView.mTransformationInfo; 8451271e2cc80b01d577e9db339459ef0222bb9320dChet Haase final DisplayList displayList = mView.mDisplayList; 846a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase switch (propertyConstant) { 847a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase case TRANSLATION_X: 848ddb715b238c098d8b561a44b9687f0bc67a4c141Dianne Hackborn info.mTranslationX = value; 849db8c9a6a4d9bf8c39f834b25611926caf21380f6Chet Haase if (displayList != null) displayList.setTranslationX(value); 850a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase break; 851a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase case TRANSLATION_Y: 852ddb715b238c098d8b561a44b9687f0bc67a4c141Dianne Hackborn info.mTranslationY = value; 853db8c9a6a4d9bf8c39f834b25611926caf21380f6Chet Haase if (displayList != null) displayList.setTranslationY(value); 854a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase break; 855a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase case ROTATION: 856ddb715b238c098d8b561a44b9687f0bc67a4c141Dianne Hackborn info.mRotation = value; 857db8c9a6a4d9bf8c39f834b25611926caf21380f6Chet Haase if (displayList != null) displayList.setRotation(value); 858a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase break; 859a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase case ROTATION_X: 860ddb715b238c098d8b561a44b9687f0bc67a4c141Dianne Hackborn info.mRotationX = value; 861db8c9a6a4d9bf8c39f834b25611926caf21380f6Chet Haase if (displayList != null) displayList.setRotationX(value); 862a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase break; 863a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase case ROTATION_Y: 864ddb715b238c098d8b561a44b9687f0bc67a4c141Dianne Hackborn info.mRotationY = value; 865db8c9a6a4d9bf8c39f834b25611926caf21380f6Chet Haase if (displayList != null) displayList.setRotationY(value); 866a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase break; 867a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase case SCALE_X: 868ddb715b238c098d8b561a44b9687f0bc67a4c141Dianne Hackborn info.mScaleX = value; 869db8c9a6a4d9bf8c39f834b25611926caf21380f6Chet Haase if (displayList != null) displayList.setScaleX(value); 870a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase break; 871a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase case SCALE_Y: 872ddb715b238c098d8b561a44b9687f0bc67a4c141Dianne Hackborn info.mScaleY = value; 873db8c9a6a4d9bf8c39f834b25611926caf21380f6Chet Haase if (displayList != null) displayList.setScaleY(value); 874a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase break; 875a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase case X: 876ddb715b238c098d8b561a44b9687f0bc67a4c141Dianne Hackborn info.mTranslationX = value - mView.mLeft; 877db8c9a6a4d9bf8c39f834b25611926caf21380f6Chet Haase if (displayList != null) displayList.setTranslationX(value - mView.mLeft); 878a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase break; 879a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase case Y: 880ddb715b238c098d8b561a44b9687f0bc67a4c141Dianne Hackborn info.mTranslationY = value - mView.mTop; 881db8c9a6a4d9bf8c39f834b25611926caf21380f6Chet Haase if (displayList != null) displayList.setTranslationY(value - mView.mTop); 882a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase break; 883a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase case ALPHA: 884ddb715b238c098d8b561a44b9687f0bc67a4c141Dianne Hackborn info.mAlpha = value; 885db8c9a6a4d9bf8c39f834b25611926caf21380f6Chet Haase if (displayList != null) displayList.setAlpha(value); 886a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase break; 887a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase } 888a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase } 889a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase 890a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase /** 891a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase * This method gets the value of the named property from the View object. 892a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase * 893a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase * @param propertyConstant The property whose value should be returned 894a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase * @return float The value of the named property 895a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase */ 896a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase private float getValue(int propertyConstant) { 897ddb715b238c098d8b561a44b9687f0bc67a4c141Dianne Hackborn final View.TransformationInfo info = mView.mTransformationInfo; 898a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase switch (propertyConstant) { 899a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase case TRANSLATION_X: 900ddb715b238c098d8b561a44b9687f0bc67a4c141Dianne Hackborn return info.mTranslationX; 901a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase case TRANSLATION_Y: 902ddb715b238c098d8b561a44b9687f0bc67a4c141Dianne Hackborn return info.mTranslationY; 903a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase case ROTATION: 904ddb715b238c098d8b561a44b9687f0bc67a4c141Dianne Hackborn return info.mRotation; 905a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase case ROTATION_X: 906ddb715b238c098d8b561a44b9687f0bc67a4c141Dianne Hackborn return info.mRotationX; 907a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase case ROTATION_Y: 908ddb715b238c098d8b561a44b9687f0bc67a4c141Dianne Hackborn return info.mRotationY; 909a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase case SCALE_X: 910ddb715b238c098d8b561a44b9687f0bc67a4c141Dianne Hackborn return info.mScaleX; 911a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase case SCALE_Y: 912ddb715b238c098d8b561a44b9687f0bc67a4c141Dianne Hackborn return info.mScaleY; 913a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase case X: 914ddb715b238c098d8b561a44b9687f0bc67a4c141Dianne Hackborn return mView.mLeft + info.mTranslationX; 915a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase case Y: 916ddb715b238c098d8b561a44b9687f0bc67a4c141Dianne Hackborn return mView.mTop + info.mTranslationY; 917a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase case ALPHA: 918ddb715b238c098d8b561a44b9687f0bc67a4c141Dianne Hackborn return info.mAlpha; 919a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase } 920a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase return 0; 921a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase } 922a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase 923a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase /** 924a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase * Utility class that handles the various Animator events. The only ones we care 925a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase * about are the end event (which we use to clean up the animator map when an animator 926a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase * finishes) and the update event (which we use to calculate the current value of each 927a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase * property and then set it on the view object). 928a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase */ 929a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase private class AnimatorEventListener 930a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase implements Animator.AnimatorListener, ValueAnimator.AnimatorUpdateListener { 931a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase @Override 932a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase public void onAnimationStart(Animator animation) { 933c1ca665827f0c34419a55c005254c1aaa0d58b40Chet Haase if (mAnimatorSetupMap != null) { 934c1ca665827f0c34419a55c005254c1aaa0d58b40Chet Haase Runnable r = mAnimatorSetupMap.get(animation); 935c1ca665827f0c34419a55c005254c1aaa0d58b40Chet Haase if (r != null) { 936c1ca665827f0c34419a55c005254c1aaa0d58b40Chet Haase r.run(); 937c1ca665827f0c34419a55c005254c1aaa0d58b40Chet Haase } 938c1ca665827f0c34419a55c005254c1aaa0d58b40Chet Haase mAnimatorSetupMap.remove(animation); 939c1ca665827f0c34419a55c005254c1aaa0d58b40Chet Haase } 940c1ca665827f0c34419a55c005254c1aaa0d58b40Chet Haase if (mAnimatorOnStartMap != null) { 941c1ca665827f0c34419a55c005254c1aaa0d58b40Chet Haase Runnable r = mAnimatorOnStartMap.get(animation); 942c1ca665827f0c34419a55c005254c1aaa0d58b40Chet Haase if (r != null) { 943c1ca665827f0c34419a55c005254c1aaa0d58b40Chet Haase r.run(); 944c1ca665827f0c34419a55c005254c1aaa0d58b40Chet Haase } 945c1ca665827f0c34419a55c005254c1aaa0d58b40Chet Haase mAnimatorOnStartMap.remove(animation); 946c1ca665827f0c34419a55c005254c1aaa0d58b40Chet Haase } 947a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase if (mListener != null) { 948a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase mListener.onAnimationStart(animation); 949a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase } 950a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase } 951a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase 952a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase @Override 953a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase public void onAnimationCancel(Animator animation) { 954a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase if (mListener != null) { 955a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase mListener.onAnimationCancel(animation); 956a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase } 957c1ca665827f0c34419a55c005254c1aaa0d58b40Chet Haase if (mAnimatorOnEndMap != null) { 958c1ca665827f0c34419a55c005254c1aaa0d58b40Chet Haase mAnimatorOnEndMap.remove(animation); 959c1ca665827f0c34419a55c005254c1aaa0d58b40Chet Haase } 960a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase } 961a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase 962a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase @Override 963a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase public void onAnimationRepeat(Animator animation) { 964a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase if (mListener != null) { 965a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase mListener.onAnimationRepeat(animation); 966a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase } 967a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase } 968a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase 969a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase @Override 970a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase public void onAnimationEnd(Animator animation) { 971563d4f2d461d264457b7e7068e2fc7b9b0bcafb3Chet Haase mView.setHasTransientState(false); 972a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase if (mListener != null) { 973a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase mListener.onAnimationEnd(animation); 974a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase } 975c1ca665827f0c34419a55c005254c1aaa0d58b40Chet Haase if (mAnimatorOnEndMap != null) { 976c1ca665827f0c34419a55c005254c1aaa0d58b40Chet Haase Runnable r = mAnimatorOnEndMap.get(animation); 977c1ca665827f0c34419a55c005254c1aaa0d58b40Chet Haase if (r != null) { 978c1ca665827f0c34419a55c005254c1aaa0d58b40Chet Haase r.run(); 979c1ca665827f0c34419a55c005254c1aaa0d58b40Chet Haase } 980c1ca665827f0c34419a55c005254c1aaa0d58b40Chet Haase mAnimatorOnEndMap.remove(animation); 981c1ca665827f0c34419a55c005254c1aaa0d58b40Chet Haase } 982c1ca665827f0c34419a55c005254c1aaa0d58b40Chet Haase if (mAnimatorCleanupMap != null) { 983c1ca665827f0c34419a55c005254c1aaa0d58b40Chet Haase Runnable r = mAnimatorCleanupMap.get(animation); 984c1ca665827f0c34419a55c005254c1aaa0d58b40Chet Haase if (r != null) { 985c1ca665827f0c34419a55c005254c1aaa0d58b40Chet Haase r.run(); 986c1ca665827f0c34419a55c005254c1aaa0d58b40Chet Haase } 987c1ca665827f0c34419a55c005254c1aaa0d58b40Chet Haase mAnimatorCleanupMap.remove(animation); 988c1ca665827f0c34419a55c005254c1aaa0d58b40Chet Haase } 989a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase mAnimatorMap.remove(animation); 990a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase } 991a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase 992a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase /** 993a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase * Calculate the current value for each property and set it on the view. Invalidate 994a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase * the view object appropriately, depending on which properties are being animated. 995a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase * 996a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase * @param animation The animator associated with the properties that need to be 997a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase * set. This animator holds the animation fraction which we will use to calculate 998a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase * the current value of each property. 999a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase */ 1000a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase @Override 1001a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase public void onAnimationUpdate(ValueAnimator animation) { 10020c6d83cc5625f967eb2e23cc7c232874cd9e60f9Chet Haase PropertyBundle propertyBundle = mAnimatorMap.get(animation); 10030c6d83cc5625f967eb2e23cc7c232874cd9e60f9Chet Haase if (propertyBundle == null) { 10040c6d83cc5625f967eb2e23cc7c232874cd9e60f9Chet Haase // Shouldn't happen, but just to play it safe 10050c6d83cc5625f967eb2e23cc7c232874cd9e60f9Chet Haase return; 10060c6d83cc5625f967eb2e23cc7c232874cd9e60f9Chet Haase } 10071271e2cc80b01d577e9db339459ef0222bb9320dChet Haase boolean useDisplayListProperties = mView.mDisplayList != null; 10089d1992deaeb3d60d5928f05b649a2cc654ba98a3Chet Haase 1009a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase // alpha requires slightly different treatment than the other (transform) properties. 1010a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase // The logic in setAlpha() is not simply setting mAlpha, plus the invalidation 1011a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase // logic is dependent on how the view handles an internal call to onSetAlpha(). 1012a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase // We track what kinds of properties are set, and how alpha is handled when it is 1013a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase // set, and perform the invalidation steps appropriately. 1014a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase boolean alphaHandled = false; 10159d1992deaeb3d60d5928f05b649a2cc654ba98a3Chet Haase if (!useDisplayListProperties) { 10169d1992deaeb3d60d5928f05b649a2cc654ba98a3Chet Haase mView.invalidateParentCaches(); 10179d1992deaeb3d60d5928f05b649a2cc654ba98a3Chet Haase } 1018a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase float fraction = animation.getAnimatedFraction(); 1019a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase int propertyMask = propertyBundle.mPropertyMask; 1020a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase if ((propertyMask & TRANSFORM_MASK) != 0) { 10219d1992deaeb3d60d5928f05b649a2cc654ba98a3Chet Haase mView.invalidateViewProperty(false, false); 1022a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase } 1023a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase ArrayList<NameValuesHolder> valueList = propertyBundle.mNameValuesHolder; 1024a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase if (valueList != null) { 1025a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase int count = valueList.size(); 1026a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase for (int i = 0; i < count; ++i) { 1027a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase NameValuesHolder values = valueList.get(i); 1028a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase float value = values.mFromValue + fraction * values.mDeltaValue; 1029a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase if (values.mNameConstant == ALPHA) { 1030a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase alphaHandled = mView.setAlphaNoInvalidation(value); 1031a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase } else { 1032a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase setValue(values.mNameConstant, value); 1033a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase } 1034a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase } 1035a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase } 1036a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase if ((propertyMask & TRANSFORM_MASK) != 0) { 1037ddb715b238c098d8b561a44b9687f0bc67a4c141Dianne Hackborn mView.mTransformationInfo.mMatrixDirty = true; 10389d1992deaeb3d60d5928f05b649a2cc654ba98a3Chet Haase if (!useDisplayListProperties) { 10394702a856973a553deb82f71b1d3b6c3db5dbf4baDianne Hackborn mView.mPrivateFlags |= View.PFLAG_DRAWN; // force another invalidation 10409d1992deaeb3d60d5928f05b649a2cc654ba98a3Chet Haase } 1041a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase } 1042a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase // invalidate(false) in all cases except if alphaHandled gets set to true 1043a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase // via the call to setAlphaNoInvalidation(), above 10449d1992deaeb3d60d5928f05b649a2cc654ba98a3Chet Haase if (alphaHandled) { 10459d1992deaeb3d60d5928f05b649a2cc654ba98a3Chet Haase mView.invalidate(true); 10469d1992deaeb3d60d5928f05b649a2cc654ba98a3Chet Haase } else { 10479d1992deaeb3d60d5928f05b649a2cc654ba98a3Chet Haase mView.invalidateViewProperty(false, false); 10489d1992deaeb3d60d5928f05b649a2cc654ba98a3Chet Haase } 1049a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase } 1050a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase } 1051a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase} 1052