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    /**
9687f4ae67c86c7044253b3e1bcec6956a8c8bf017Chet Haase     * Listener for the lifecycle events of the underlying ValueAnimator object.
97a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase     */
98a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase    private Animator.AnimatorListener mListener = null;
99a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase
100a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase    /**
10187f4ae67c86c7044253b3e1bcec6956a8c8bf017Chet Haase     * Listener for the update events of the underlying ValueAnimator object.
10287f4ae67c86c7044253b3e1bcec6956a8c8bf017Chet Haase     */
10387f4ae67c86c7044253b3e1bcec6956a8c8bf017Chet Haase    private ValueAnimator.AnimatorUpdateListener mUpdateListener = null;
10487f4ae67c86c7044253b3e1bcec6956a8c8bf017Chet Haase
10587f4ae67c86c7044253b3e1bcec6956a8c8bf017Chet Haase    /**
106d40acfb89e3222e8da516254341a9489de7fd07bCyril Mottier     * A lazily-created ValueAnimator used in order to get some default animator properties
107d40acfb89e3222e8da516254341a9489de7fd07bCyril Mottier     * (duration, start delay, interpolator, etc.).
108d40acfb89e3222e8da516254341a9489de7fd07bCyril Mottier     */
109d40acfb89e3222e8da516254341a9489de7fd07bCyril Mottier    private ValueAnimator mTempValueAnimator;
110d40acfb89e3222e8da516254341a9489de7fd07bCyril Mottier
111d40acfb89e3222e8da516254341a9489de7fd07bCyril Mottier    /**
112a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase     * This listener is the mechanism by which the underlying Animator causes changes to the
113a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase     * properties currently being animated, as well as the cleanup after an animation is
114a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase     * complete.
115a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase     */
116a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase    private AnimatorEventListener mAnimatorEventListener = new AnimatorEventListener();
117a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase
118a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase    /**
119a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase     * This list holds the properties that have been asked to animate. We allow the caller to
120a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase     * request several animations prior to actually starting the underlying animator. This
121a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase     * enables us to run one single animator to handle several properties in parallel. Each
122a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase     * property is tossed onto the pending list until the animation actually starts (which is
123a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase     * done by posting it onto mView), at which time the pending list is cleared and the properties
124a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase     * on that list are added to the list of properties associated with that animator.
125a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase     */
126a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase    ArrayList<NameValuesHolder> mPendingAnimations = new ArrayList<NameValuesHolder>();
127c1ca665827f0c34419a55c005254c1aaa0d58b40Chet Haase    private Runnable mPendingSetupAction;
128c1ca665827f0c34419a55c005254c1aaa0d58b40Chet Haase    private Runnable mPendingCleanupAction;
129c1ca665827f0c34419a55c005254c1aaa0d58b40Chet Haase    private Runnable mPendingOnStartAction;
130c1ca665827f0c34419a55c005254c1aaa0d58b40Chet Haase    private Runnable mPendingOnEndAction;
131a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase
132a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase    /**
133a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase     * Constants used to associate a property being requested and the mechanism used to set
134d666cf320db4134938f72b0ffe18212997f8c8d8Chet Haase     * the property (this class calls directly into View to set the properties in question).
135a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase     */
136a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase    private static final int NONE           = 0x0000;
137a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase    private static final int TRANSLATION_X  = 0x0001;
138a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase    private static final int TRANSLATION_Y  = 0x0002;
139a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase    private static final int SCALE_X        = 0x0004;
140a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase    private static final int SCALE_Y        = 0x0008;
141a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase    private static final int ROTATION       = 0x0010;
142a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase    private static final int ROTATION_X     = 0x0020;
143a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase    private static final int ROTATION_Y     = 0x0040;
144a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase    private static final int X              = 0x0080;
145a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase    private static final int Y              = 0x0100;
146a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase    private static final int ALPHA          = 0x0200;
147a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase
148a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase    private static final int TRANSFORM_MASK = TRANSLATION_X | TRANSLATION_Y | SCALE_X | SCALE_Y |
149a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase            ROTATION | ROTATION_X | ROTATION_Y | X | Y;
150a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase
151a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase    /**
152a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase     * The mechanism by which the user can request several properties that are then animated
153a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase     * together works by posting this Runnable to start the underlying Animator. Every time
154a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase     * a property animation is requested, we cancel any previous postings of the Runnable
155a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase     * and re-post it. This means that we will only ever run the Runnable (and thus start the
156a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase     * underlying animator) after the caller is done setting the properties that should be
157a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase     * animated together.
158a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase     */
159a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase    private Runnable mAnimationStarter = new Runnable() {
160a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase        @Override
161a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase        public void run() {
162a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase            startAnimation();
163a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase        }
164a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase    };
165a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase
166a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase    /**
167a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase     * This class holds information about the overall animation being run on the set of
168a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase     * properties. The mask describes which properties are being animated and the
169a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase     * values holder is the list of all property/value objects.
170a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase     */
171a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase    private static class PropertyBundle {
172a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase        int mPropertyMask;
173a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase        ArrayList<NameValuesHolder> mNameValuesHolder;
174ba592d200390d89723682f1a7e40d308d7804b36Chet Haase
175a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase        PropertyBundle(int propertyMask, ArrayList<NameValuesHolder> nameValuesHolder) {
176a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase            mPropertyMask = propertyMask;
177a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase            mNameValuesHolder = nameValuesHolder;
178a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase        }
179ba592d200390d89723682f1a7e40d308d7804b36Chet Haase
180ba592d200390d89723682f1a7e40d308d7804b36Chet Haase        /**
181ba592d200390d89723682f1a7e40d308d7804b36Chet Haase         * Removes the given property from being animated as a part of this
182ba592d200390d89723682f1a7e40d308d7804b36Chet Haase         * PropertyBundle. If the property was a part of this bundle, it returns
183ba592d200390d89723682f1a7e40d308d7804b36Chet Haase         * true to indicate that it was, in fact, canceled. This is an indication
184ba592d200390d89723682f1a7e40d308d7804b36Chet Haase         * to the caller that a cancellation actually occurred.
185ba592d200390d89723682f1a7e40d308d7804b36Chet Haase         *
186ba592d200390d89723682f1a7e40d308d7804b36Chet Haase         * @param propertyConstant The property whose cancellation is requested.
187ba592d200390d89723682f1a7e40d308d7804b36Chet Haase         * @return true if the given property is a part of this bundle and if it
188ba592d200390d89723682f1a7e40d308d7804b36Chet Haase         * has therefore been canceled.
189ba592d200390d89723682f1a7e40d308d7804b36Chet Haase         */
190ba592d200390d89723682f1a7e40d308d7804b36Chet Haase        boolean cancel(int propertyConstant) {
191ba592d200390d89723682f1a7e40d308d7804b36Chet Haase            if ((mPropertyMask & propertyConstant) != 0 && mNameValuesHolder != null) {
192ba592d200390d89723682f1a7e40d308d7804b36Chet Haase                int count = mNameValuesHolder.size();
193ba592d200390d89723682f1a7e40d308d7804b36Chet Haase                for (int i = 0; i < count; ++i) {
194ba592d200390d89723682f1a7e40d308d7804b36Chet Haase                    NameValuesHolder nameValuesHolder = mNameValuesHolder.get(i);
195ba592d200390d89723682f1a7e40d308d7804b36Chet Haase                    if (nameValuesHolder.mNameConstant == propertyConstant) {
196ba592d200390d89723682f1a7e40d308d7804b36Chet Haase                        mNameValuesHolder.remove(i);
197ba592d200390d89723682f1a7e40d308d7804b36Chet Haase                        mPropertyMask &= ~propertyConstant;
198ba592d200390d89723682f1a7e40d308d7804b36Chet Haase                        return true;
199ba592d200390d89723682f1a7e40d308d7804b36Chet Haase                    }
200ba592d200390d89723682f1a7e40d308d7804b36Chet Haase                }
201ba592d200390d89723682f1a7e40d308d7804b36Chet Haase            }
202ba592d200390d89723682f1a7e40d308d7804b36Chet Haase            return false;
203ba592d200390d89723682f1a7e40d308d7804b36Chet Haase        }
204a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase    }
205a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase
206a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase    /**
207a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase     * This list tracks the list of properties being animated by any particular animator.
208a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase     * In most situations, there would only ever be one animator running at a time. But it is
209a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase     * possible to request some properties to animate together, then while those properties
210a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase     * are animating, to request some other properties to animate together. The way that
211a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase     * works is by having this map associate the group of properties being animated with the
212a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase     * animator handling the animation. On every update event for an Animator, we ask the
213a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase     * map for the associated properties and set them accordingly.
214a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase     */
215a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase    private HashMap<Animator, PropertyBundle> mAnimatorMap =
216a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase            new HashMap<Animator, PropertyBundle>();
217c1ca665827f0c34419a55c005254c1aaa0d58b40Chet Haase    private HashMap<Animator, Runnable> mAnimatorSetupMap;
218c1ca665827f0c34419a55c005254c1aaa0d58b40Chet Haase    private HashMap<Animator, Runnable> mAnimatorCleanupMap;
219c1ca665827f0c34419a55c005254c1aaa0d58b40Chet Haase    private HashMap<Animator, Runnable> mAnimatorOnStartMap;
220c1ca665827f0c34419a55c005254c1aaa0d58b40Chet Haase    private HashMap<Animator, Runnable> mAnimatorOnEndMap;
221a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase
222a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase    /**
223a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase     * This is the information we need to set each property during the animation.
224a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase     * mNameConstant is used to set the appropriate field in View, and the from/delta
225a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase     * values are used to calculate the animated value for a given animation fraction
226a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase     * during the animation.
227a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase     */
228a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase    private static class NameValuesHolder {
229a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase        int mNameConstant;
230a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase        float mFromValue;
231a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase        float mDeltaValue;
232a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase        NameValuesHolder(int nameConstant, float fromValue, float deltaValue) {
233a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase            mNameConstant = nameConstant;
234a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase            mFromValue = fromValue;
235a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase            mDeltaValue = deltaValue;
236a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase        }
237a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase    }
238a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase
239a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase    /**
240a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase     * Constructor, called by View. This is private by design, as the user should only
241a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase     * get a ViewPropertyAnimator by calling View.animate().
242a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase     *
243a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase     * @param view The View associated with this ViewPropertyAnimator
244a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase     */
245a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase    ViewPropertyAnimator(View view) {
246a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase        mView = view;
247ddb715b238c098d8b561a44b9687f0bc67a4c141Dianne Hackborn        view.ensureTransformationInfo();
248a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase    }
249a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase
250a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase    /**
251a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase     * Sets the duration for the underlying animator that animates the requested properties.
252a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase     * By default, the animator uses the default value for ValueAnimator. Calling this method
253a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase     * will cause the declared value to be used instead.
254a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase     * @param duration The length of ensuing property animations, in milliseconds. The value
255a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase     * cannot be negative.
256a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase     * @return This object, allowing calls to methods in this class to be chained.
257a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase     */
258a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase    public ViewPropertyAnimator setDuration(long duration) {
259a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase        if (duration < 0) {
260a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase            throw new IllegalArgumentException("Animators cannot have negative duration: " +
261a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase                    duration);
262a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase        }
263a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase        mDurationSet = true;
264a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase        mDuration = duration;
265a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase        return this;
266a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase    }
267a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase
268a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase    /**
2698d5f808f70c1d47437eaf49234c1b3a23c244040Chet Haase     * Returns the current duration of property animations. If the duration was set on this
2708d5f808f70c1d47437eaf49234c1b3a23c244040Chet Haase     * object, that value is returned. Otherwise, the default value of the underlying Animator
2718d5f808f70c1d47437eaf49234c1b3a23c244040Chet Haase     * is returned.
2728d5f808f70c1d47437eaf49234c1b3a23c244040Chet Haase     *
2738d5f808f70c1d47437eaf49234c1b3a23c244040Chet Haase     * @see #setDuration(long)
2748d5f808f70c1d47437eaf49234c1b3a23c244040Chet Haase     * @return The duration of animations, in milliseconds.
2758d5f808f70c1d47437eaf49234c1b3a23c244040Chet Haase     */
2768d5f808f70c1d47437eaf49234c1b3a23c244040Chet Haase    public long getDuration() {
277cbbd93ae701b9af2e5054d59286bdbf6275c2838Chet Haase        if (mDurationSet) {
278cbbd93ae701b9af2e5054d59286bdbf6275c2838Chet Haase            return mDuration;
2798d5f808f70c1d47437eaf49234c1b3a23c244040Chet Haase        } else {
2808d5f808f70c1d47437eaf49234c1b3a23c244040Chet Haase            // Just return the default from ValueAnimator, since that's what we'd get if
2818d5f808f70c1d47437eaf49234c1b3a23c244040Chet Haase            // the value has not been set otherwise
282d40acfb89e3222e8da516254341a9489de7fd07bCyril Mottier            if (mTempValueAnimator == null) {
283d40acfb89e3222e8da516254341a9489de7fd07bCyril Mottier                mTempValueAnimator = new ValueAnimator();
284d40acfb89e3222e8da516254341a9489de7fd07bCyril Mottier            }
285d40acfb89e3222e8da516254341a9489de7fd07bCyril Mottier            return mTempValueAnimator.getDuration();
2868d5f808f70c1d47437eaf49234c1b3a23c244040Chet Haase        }
2878d5f808f70c1d47437eaf49234c1b3a23c244040Chet Haase    }
2888d5f808f70c1d47437eaf49234c1b3a23c244040Chet Haase
2898d5f808f70c1d47437eaf49234c1b3a23c244040Chet Haase    /**
2908d5f808f70c1d47437eaf49234c1b3a23c244040Chet Haase     * Returns the current startDelay of property animations. If the startDelay was set on this
2918d5f808f70c1d47437eaf49234c1b3a23c244040Chet Haase     * object, that value is returned. Otherwise, the default value of the underlying Animator
2928d5f808f70c1d47437eaf49234c1b3a23c244040Chet Haase     * is returned.
2938d5f808f70c1d47437eaf49234c1b3a23c244040Chet Haase     *
2948d5f808f70c1d47437eaf49234c1b3a23c244040Chet Haase     * @see #setStartDelay(long)
2958d5f808f70c1d47437eaf49234c1b3a23c244040Chet Haase     * @return The startDelay of animations, in milliseconds.
2968d5f808f70c1d47437eaf49234c1b3a23c244040Chet Haase     */
2978d5f808f70c1d47437eaf49234c1b3a23c244040Chet Haase    public long getStartDelay() {
2988d5f808f70c1d47437eaf49234c1b3a23c244040Chet Haase        if (mStartDelaySet) {
2998d5f808f70c1d47437eaf49234c1b3a23c244040Chet Haase            return mStartDelay;
3008d5f808f70c1d47437eaf49234c1b3a23c244040Chet Haase        } else {
3018d5f808f70c1d47437eaf49234c1b3a23c244040Chet Haase            // Just return the default from ValueAnimator (0), since that's what we'd get if
3028d5f808f70c1d47437eaf49234c1b3a23c244040Chet Haase            // the value has not been set otherwise
3038d5f808f70c1d47437eaf49234c1b3a23c244040Chet Haase            return 0;
3048d5f808f70c1d47437eaf49234c1b3a23c244040Chet Haase        }
3058d5f808f70c1d47437eaf49234c1b3a23c244040Chet Haase    }
3068d5f808f70c1d47437eaf49234c1b3a23c244040Chet Haase
3078d5f808f70c1d47437eaf49234c1b3a23c244040Chet Haase    /**
3088d5f808f70c1d47437eaf49234c1b3a23c244040Chet Haase     * Sets the startDelay for the underlying animator that animates the requested properties.
3098d5f808f70c1d47437eaf49234c1b3a23c244040Chet Haase     * By default, the animator uses the default value for ValueAnimator. Calling this method
3108d5f808f70c1d47437eaf49234c1b3a23c244040Chet Haase     * will cause the declared value to be used instead.
3118d5f808f70c1d47437eaf49234c1b3a23c244040Chet Haase     * @param startDelay The delay of ensuing property animations, in milliseconds. The value
3128d5f808f70c1d47437eaf49234c1b3a23c244040Chet Haase     * cannot be negative.
3138d5f808f70c1d47437eaf49234c1b3a23c244040Chet Haase     * @return This object, allowing calls to methods in this class to be chained.
3148d5f808f70c1d47437eaf49234c1b3a23c244040Chet Haase     */
3158d5f808f70c1d47437eaf49234c1b3a23c244040Chet Haase    public ViewPropertyAnimator setStartDelay(long startDelay) {
3168d5f808f70c1d47437eaf49234c1b3a23c244040Chet Haase        if (startDelay < 0) {
3178d5f808f70c1d47437eaf49234c1b3a23c244040Chet Haase            throw new IllegalArgumentException("Animators cannot have negative duration: " +
3188d5f808f70c1d47437eaf49234c1b3a23c244040Chet Haase                    startDelay);
3198d5f808f70c1d47437eaf49234c1b3a23c244040Chet Haase        }
3208d5f808f70c1d47437eaf49234c1b3a23c244040Chet Haase        mStartDelaySet = true;
3218d5f808f70c1d47437eaf49234c1b3a23c244040Chet Haase        mStartDelay = startDelay;
3228d5f808f70c1d47437eaf49234c1b3a23c244040Chet Haase        return this;
3238d5f808f70c1d47437eaf49234c1b3a23c244040Chet Haase    }
3248d5f808f70c1d47437eaf49234c1b3a23c244040Chet Haase
3258d5f808f70c1d47437eaf49234c1b3a23c244040Chet Haase    /**
326a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase     * Sets the interpolator for the underlying animator that animates the requested properties.
327a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase     * By default, the animator uses the default interpolator for ValueAnimator. Calling this method
328a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase     * will cause the declared object to be used instead.
329a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase     *
330a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase     * @param interpolator The TimeInterpolator to be used for ensuing property animations.
331a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase     * @return This object, allowing calls to methods in this class to be chained.
332a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase     */
333a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase    public ViewPropertyAnimator setInterpolator(TimeInterpolator interpolator) {
334a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase        mInterpolatorSet = true;
335a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase        mInterpolator = interpolator;
336a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase        return this;
337a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase    }
338a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase
339a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase    /**
340430742f09063574271e6c4091de13b9b9e762514Chet Haase     * Returns the timing interpolator that this animation uses.
341430742f09063574271e6c4091de13b9b9e762514Chet Haase     *
342430742f09063574271e6c4091de13b9b9e762514Chet Haase     * @return The timing interpolator for this animation.
343430742f09063574271e6c4091de13b9b9e762514Chet Haase     */
344430742f09063574271e6c4091de13b9b9e762514Chet Haase    public TimeInterpolator getInterpolator() {
345d40acfb89e3222e8da516254341a9489de7fd07bCyril Mottier        if (mInterpolatorSet) {
346d40acfb89e3222e8da516254341a9489de7fd07bCyril Mottier            return mInterpolator;
347d40acfb89e3222e8da516254341a9489de7fd07bCyril Mottier        } else {
348d40acfb89e3222e8da516254341a9489de7fd07bCyril Mottier            // Just return the default from ValueAnimator, since that's what we'd get if
349d40acfb89e3222e8da516254341a9489de7fd07bCyril Mottier            // the value has not been set otherwise
350d40acfb89e3222e8da516254341a9489de7fd07bCyril Mottier            if (mTempValueAnimator == null) {
351d40acfb89e3222e8da516254341a9489de7fd07bCyril Mottier                mTempValueAnimator = new ValueAnimator();
352d40acfb89e3222e8da516254341a9489de7fd07bCyril Mottier            }
353d40acfb89e3222e8da516254341a9489de7fd07bCyril Mottier            return mTempValueAnimator.getInterpolator();
354d40acfb89e3222e8da516254341a9489de7fd07bCyril Mottier        }
355430742f09063574271e6c4091de13b9b9e762514Chet Haase    }
356430742f09063574271e6c4091de13b9b9e762514Chet Haase
357430742f09063574271e6c4091de13b9b9e762514Chet Haase    /**
358a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase     * Sets a listener for events in the underlying Animators that run the property
359a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase     * animations.
360a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase     *
36187f4ae67c86c7044253b3e1bcec6956a8c8bf017Chet Haase     * @see Animator.AnimatorListener
36287f4ae67c86c7044253b3e1bcec6956a8c8bf017Chet Haase     *
36387f4ae67c86c7044253b3e1bcec6956a8c8bf017Chet Haase     * @param listener The listener to be called with AnimatorListener events. A value of
36487f4ae67c86c7044253b3e1bcec6956a8c8bf017Chet Haase     * <code>null</code> removes any existing listener.
365a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase     * @return This object, allowing calls to methods in this class to be chained.
366a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase     */
367a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase    public ViewPropertyAnimator setListener(Animator.AnimatorListener listener) {
368a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase        mListener = listener;
369a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase        return this;
370a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase    }
371a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase
372a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase    /**
37387f4ae67c86c7044253b3e1bcec6956a8c8bf017Chet Haase     * Sets a listener for update events in the underlying ValueAnimator that runs
37487f4ae67c86c7044253b3e1bcec6956a8c8bf017Chet Haase     * the property animations. Note that the underlying animator is animating between
37587f4ae67c86c7044253b3e1bcec6956a8c8bf017Chet Haase     * 0 and 1 (these values are then turned into the actual property values internally
37687f4ae67c86c7044253b3e1bcec6956a8c8bf017Chet Haase     * by ViewPropertyAnimator). So the animator cannot give information on the current
37787f4ae67c86c7044253b3e1bcec6956a8c8bf017Chet Haase     * values of the properties being animated by this ViewPropertyAnimator, although
37887f4ae67c86c7044253b3e1bcec6956a8c8bf017Chet Haase     * the view object itself can be queried to get the current values.
37987f4ae67c86c7044253b3e1bcec6956a8c8bf017Chet Haase     *
38087f4ae67c86c7044253b3e1bcec6956a8c8bf017Chet Haase     * @see android.animation.ValueAnimator.AnimatorUpdateListener
38187f4ae67c86c7044253b3e1bcec6956a8c8bf017Chet Haase     *
38287f4ae67c86c7044253b3e1bcec6956a8c8bf017Chet Haase     * @param listener The listener to be called with update events. A value of
38387f4ae67c86c7044253b3e1bcec6956a8c8bf017Chet Haase     * <code>null</code> removes any existing listener.
38487f4ae67c86c7044253b3e1bcec6956a8c8bf017Chet Haase     * @return This object, allowing calls to methods in this class to be chained.
38587f4ae67c86c7044253b3e1bcec6956a8c8bf017Chet Haase     */
38687f4ae67c86c7044253b3e1bcec6956a8c8bf017Chet Haase    public ViewPropertyAnimator setUpdateListener(ValueAnimator.AnimatorUpdateListener listener) {
38787f4ae67c86c7044253b3e1bcec6956a8c8bf017Chet Haase        mUpdateListener = listener;
38887f4ae67c86c7044253b3e1bcec6956a8c8bf017Chet Haase        return this;
38987f4ae67c86c7044253b3e1bcec6956a8c8bf017Chet Haase    }
39087f4ae67c86c7044253b3e1bcec6956a8c8bf017Chet Haase
39187f4ae67c86c7044253b3e1bcec6956a8c8bf017Chet Haase    /**
3928d5f808f70c1d47437eaf49234c1b3a23c244040Chet Haase     * Starts the currently pending property animations immediately. Calling <code>start()</code>
3938d5f808f70c1d47437eaf49234c1b3a23c244040Chet Haase     * is optional because all animations start automatically at the next opportunity. However,
3948d5f808f70c1d47437eaf49234c1b3a23c244040Chet Haase     * if the animations are needed to start immediately and synchronously (not at the time when
3958d5f808f70c1d47437eaf49234c1b3a23c244040Chet Haase     * the next event is processed by the hierarchy, which is when the animations would begin
3968d5f808f70c1d47437eaf49234c1b3a23c244040Chet Haase     * otherwise), then this method can be used.
3978d5f808f70c1d47437eaf49234c1b3a23c244040Chet Haase     */
3988d5f808f70c1d47437eaf49234c1b3a23c244040Chet Haase    public void start() {
399500998d401e1c936bf60facecd5e9699d2eadb66Michael Jurka        mView.removeCallbacks(mAnimationStarter);
4008d5f808f70c1d47437eaf49234c1b3a23c244040Chet Haase        startAnimation();
4018d5f808f70c1d47437eaf49234c1b3a23c244040Chet Haase    }
4028d5f808f70c1d47437eaf49234c1b3a23c244040Chet Haase
4038d5f808f70c1d47437eaf49234c1b3a23c244040Chet Haase    /**
4048d5f808f70c1d47437eaf49234c1b3a23c244040Chet Haase     * Cancels all property animations that are currently running or pending.
4058d5f808f70c1d47437eaf49234c1b3a23c244040Chet Haase     */
4068d5f808f70c1d47437eaf49234c1b3a23c244040Chet Haase    public void cancel() {
4078d5f808f70c1d47437eaf49234c1b3a23c244040Chet Haase        if (mAnimatorMap.size() > 0) {
4088d5f808f70c1d47437eaf49234c1b3a23c244040Chet Haase            HashMap<Animator, PropertyBundle> mAnimatorMapCopy =
4098d5f808f70c1d47437eaf49234c1b3a23c244040Chet Haase                    (HashMap<Animator, PropertyBundle>)mAnimatorMap.clone();
4108d5f808f70c1d47437eaf49234c1b3a23c244040Chet Haase            Set<Animator> animatorSet = mAnimatorMapCopy.keySet();
4118d5f808f70c1d47437eaf49234c1b3a23c244040Chet Haase            for (Animator runningAnim : animatorSet) {
4128d5f808f70c1d47437eaf49234c1b3a23c244040Chet Haase                runningAnim.cancel();
4138d5f808f70c1d47437eaf49234c1b3a23c244040Chet Haase            }
4148d5f808f70c1d47437eaf49234c1b3a23c244040Chet Haase        }
4158d5f808f70c1d47437eaf49234c1b3a23c244040Chet Haase        mPendingAnimations.clear();
4163a000a52d6863bd1c6c9822a9cfd83e00f3aaf79Chet Haase        mView.removeCallbacks(mAnimationStarter);
4178d5f808f70c1d47437eaf49234c1b3a23c244040Chet Haase    }
4188d5f808f70c1d47437eaf49234c1b3a23c244040Chet Haase
4198d5f808f70c1d47437eaf49234c1b3a23c244040Chet Haase    /**
420a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase     * This method will cause the View's <code>x</code> property to be animated to the
421d666cf320db4134938f72b0ffe18212997f8c8d8Chet Haase     * specified value. Animations already running on the property will be canceled.
422a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase     *
423a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase     * @param value The value to be animated to.
424a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase     * @see View#setX(float)
425a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase     * @return This object, allowing calls to methods in this class to be chained.
426a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase     */
427a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase    public ViewPropertyAnimator x(float value) {
428a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase        animateProperty(X, value);
429a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase        return this;
430a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase    }
431a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase
432a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase    /**
433a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase     * This method will cause the View's <code>x</code> property to be animated by the
434d666cf320db4134938f72b0ffe18212997f8c8d8Chet Haase     * specified value. Animations already running on the property will be canceled.
435a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase     *
436a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase     * @param value The amount to be animated by, as an offset from the current value.
437a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase     * @see View#setX(float)
438a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase     * @return This object, allowing calls to methods in this class to be chained.
439a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase     */
440a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase    public ViewPropertyAnimator xBy(float value) {
441a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase        animatePropertyBy(X, value);
442a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase        return this;
443a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase    }
444a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase
445a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase    /**
446a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase     * This method will cause the View's <code>y</code> property to be animated to the
447d666cf320db4134938f72b0ffe18212997f8c8d8Chet Haase     * specified value. Animations already running on the property will be canceled.
448a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase     *
449a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase     * @param value The value to be animated to.
450a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase     * @see View#setY(float)
451a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase     * @return This object, allowing calls to methods in this class to be chained.
452a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase     */
453a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase    public ViewPropertyAnimator y(float value) {
454a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase        animateProperty(Y, value);
455a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase        return this;
456a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase    }
457a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase
458a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase    /**
459a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase     * This method will cause the View's <code>y</code> property to be animated by the
460d666cf320db4134938f72b0ffe18212997f8c8d8Chet Haase     * specified value. Animations already running on the property will be canceled.
461a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase     *
462a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase     * @param value The amount to be animated by, as an offset from the current value.
463a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase     * @see View#setY(float)
464a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase     * @return This object, allowing calls to methods in this class to be chained.
465a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase     */
466a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase    public ViewPropertyAnimator yBy(float value) {
467a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase        animatePropertyBy(Y, value);
468a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase        return this;
469a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase    }
470a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase
471a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase    /**
472a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase     * This method will cause the View's <code>rotation</code> property to be animated to the
473d666cf320db4134938f72b0ffe18212997f8c8d8Chet Haase     * specified value. Animations already running on the property will be canceled.
474a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase     *
475a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase     * @param value The value to be animated to.
476a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase     * @see View#setRotation(float)
477a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase     * @return This object, allowing calls to methods in this class to be chained.
478a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase     */
479a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase    public ViewPropertyAnimator rotation(float value) {
480a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase        animateProperty(ROTATION, value);
481a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase        return this;
482a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase    }
483a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase
484a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase    /**
485a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase     * This method will cause the View's <code>rotation</code> property to be animated by the
486d666cf320db4134938f72b0ffe18212997f8c8d8Chet Haase     * specified value. Animations already running on the property will be canceled.
487a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase     *
488a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase     * @param value The amount to be animated by, as an offset from the current value.
489a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase     * @see View#setRotation(float)
490a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase     * @return This object, allowing calls to methods in this class to be chained.
491a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase     */
492a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase    public ViewPropertyAnimator rotationBy(float value) {
493a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase        animatePropertyBy(ROTATION, value);
494a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase        return this;
495a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase    }
496a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase
497a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase    /**
498a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase     * This method will cause the View's <code>rotationX</code> property to be animated to the
499d666cf320db4134938f72b0ffe18212997f8c8d8Chet Haase     * specified value. Animations already running on the property will be canceled.
500a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase     *
501a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase     * @param value The value to be animated to.
502a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase     * @see View#setRotationX(float)
503a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase     * @return This object, allowing calls to methods in this class to be chained.
504a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase     */
505a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase    public ViewPropertyAnimator rotationX(float value) {
506a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase        animateProperty(ROTATION_X, value);
507a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase        return this;
508a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase    }
509a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase
510a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase    /**
511a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase     * This method will cause the View's <code>rotationX</code> property to be animated by the
512d666cf320db4134938f72b0ffe18212997f8c8d8Chet Haase     * specified value. Animations already running on the property will be canceled.
513a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase     *
514a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase     * @param value The amount to be animated by, as an offset from the current value.
515a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase     * @see View#setRotationX(float)
516a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase     * @return This object, allowing calls to methods in this class to be chained.
517a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase     */
518a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase    public ViewPropertyAnimator rotationXBy(float value) {
519a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase        animatePropertyBy(ROTATION_X, value);
520a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase        return this;
521a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase    }
522a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase
523a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase    /**
524a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase     * This method will cause the View's <code>rotationY</code> property to be animated to the
525d666cf320db4134938f72b0ffe18212997f8c8d8Chet Haase     * specified value. Animations already running on the property will be canceled.
526a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase     *
527a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase     * @param value The value to be animated to.
528a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase     * @see View#setRotationY(float)
529a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase     * @return This object, allowing calls to methods in this class to be chained.
530a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase     */
531a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase    public ViewPropertyAnimator rotationY(float value) {
532a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase        animateProperty(ROTATION_Y, value);
533a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase        return this;
534a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase    }
535a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase
536a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase    /**
537a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase     * This method will cause the View's <code>rotationY</code> property to be animated by the
538d666cf320db4134938f72b0ffe18212997f8c8d8Chet Haase     * specified value. Animations already running on the property will be canceled.
539a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase     *
540a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase     * @param value The amount to be animated by, as an offset from the current value.
541a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase     * @see View#setRotationY(float)
542a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase     * @return This object, allowing calls to methods in this class to be chained.
543a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase     */
544a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase    public ViewPropertyAnimator rotationYBy(float value) {
545a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase        animatePropertyBy(ROTATION_Y, value);
546a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase        return this;
547a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase    }
548a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase
549a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase    /**
550a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase     * This method will cause the View's <code>translationX</code> property to be animated to the
551d666cf320db4134938f72b0ffe18212997f8c8d8Chet Haase     * specified value. Animations already running on the property will be canceled.
552a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase     *
553a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase     * @param value The value to be animated to.
554a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase     * @see View#setTranslationX(float)
555a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase     * @return This object, allowing calls to methods in this class to be chained.
556a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase     */
557a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase    public ViewPropertyAnimator translationX(float value) {
558a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase        animateProperty(TRANSLATION_X, value);
559a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase        return this;
560a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase    }
561a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase
562a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase    /**
563a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase     * This method will cause the View's <code>translationX</code> property to be animated by the
564d666cf320db4134938f72b0ffe18212997f8c8d8Chet Haase     * specified value. Animations already running on the property will be canceled.
565a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase     *
566a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase     * @param value The amount to be animated by, as an offset from the current value.
567a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase     * @see View#setTranslationX(float)
568a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase     * @return This object, allowing calls to methods in this class to be chained.
569a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase     */
570a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase    public ViewPropertyAnimator translationXBy(float value) {
571a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase        animatePropertyBy(TRANSLATION_X, value);
572a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase        return this;
573a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase    }
574a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase
575a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase    /**
576a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase     * This method will cause the View's <code>translationY</code> property to be animated to the
577d666cf320db4134938f72b0ffe18212997f8c8d8Chet Haase     * specified value. Animations already running on the property will be canceled.
578a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase     *
579a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase     * @param value The value to be animated to.
580a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase     * @see View#setTranslationY(float)
581a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase     * @return This object, allowing calls to methods in this class to be chained.
582a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase     */
583a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase    public ViewPropertyAnimator translationY(float value) {
584a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase        animateProperty(TRANSLATION_Y, value);
585a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase        return this;
586a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase    }
587a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase
588a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase    /**
589a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase     * This method will cause the View's <code>translationY</code> property to be animated by the
590d666cf320db4134938f72b0ffe18212997f8c8d8Chet Haase     * specified value. Animations already running on the property will be canceled.
591a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase     *
592a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase     * @param value The amount to be animated by, as an offset from the current value.
593a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase     * @see View#setTranslationY(float)
594a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase     * @return This object, allowing calls to methods in this class to be chained.
595a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase     */
596a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase    public ViewPropertyAnimator translationYBy(float value) {
597a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase        animatePropertyBy(TRANSLATION_Y, value);
598a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase        return this;
599a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase    }
600a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase
601a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase    /**
602a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase     * This method will cause the View's <code>scaleX</code> property to be animated to the
603d666cf320db4134938f72b0ffe18212997f8c8d8Chet Haase     * specified value. Animations already running on the property will be canceled.
604a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase     *
605a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase     * @param value The value to be animated to.
606a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase     * @see View#setScaleX(float)
607a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase     * @return This object, allowing calls to methods in this class to be chained.
608a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase     */
609a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase    public ViewPropertyAnimator scaleX(float value) {
610a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase        animateProperty(SCALE_X, value);
611a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase        return this;
612a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase    }
613a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase
614a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase    /**
615a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase     * This method will cause the View's <code>scaleX</code> property to be animated by the
616d666cf320db4134938f72b0ffe18212997f8c8d8Chet Haase     * specified value. Animations already running on the property will be canceled.
617a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase     *
618a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase     * @param value The amount to be animated by, as an offset from the current value.
619a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase     * @see View#setScaleX(float)
620a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase     * @return This object, allowing calls to methods in this class to be chained.
621a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase     */
622a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase    public ViewPropertyAnimator scaleXBy(float value) {
623a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase        animatePropertyBy(SCALE_X, value);
624a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase        return this;
625a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase    }
626a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase
627a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase    /**
628a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase     * This method will cause the View's <code>scaleY</code> property to be animated to the
629d666cf320db4134938f72b0ffe18212997f8c8d8Chet Haase     * specified value. Animations already running on the property will be canceled.
630a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase     *
631a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase     * @param value The value to be animated to.
632a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase     * @see View#setScaleY(float)
633a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase     * @return This object, allowing calls to methods in this class to be chained.
634a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase     */
635a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase    public ViewPropertyAnimator scaleY(float value) {
636a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase        animateProperty(SCALE_Y, value);
637a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase        return this;
638a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase    }
639a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase
640a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase    /**
641a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase     * This method will cause the View's <code>scaleY</code> property to be animated by the
642d666cf320db4134938f72b0ffe18212997f8c8d8Chet Haase     * specified value. Animations already running on the property will be canceled.
643a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase     *
644a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase     * @param value The amount to be animated by, as an offset from the current value.
645a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase     * @see View#setScaleY(float)
646a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase     * @return This object, allowing calls to methods in this class to be chained.
647a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase     */
648a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase    public ViewPropertyAnimator scaleYBy(float value) {
649a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase        animatePropertyBy(SCALE_Y, value);
650a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase        return this;
651a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase    }
652a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase
653a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase    /**
654a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase     * This method will cause the View's <code>alpha</code> property to be animated to the
655d666cf320db4134938f72b0ffe18212997f8c8d8Chet Haase     * specified value. Animations already running on the property will be canceled.
656a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase     *
657a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase     * @param value The value to be animated to.
658a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase     * @see View#setAlpha(float)
659a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase     * @return This object, allowing calls to methods in this class to be chained.
660a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase     */
661a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase    public ViewPropertyAnimator alpha(float value) {
662a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase        animateProperty(ALPHA, value);
663a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase        return this;
664a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase    }
665a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase
666a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase    /**
667a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase     * This method will cause the View's <code>alpha</code> property to be animated by the
668d666cf320db4134938f72b0ffe18212997f8c8d8Chet Haase     * specified value. Animations already running on the property will be canceled.
669a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase     *
670a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase     * @param value The amount to be animated by, as an offset from the current value.
671a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase     * @see View#setAlpha(float)
672a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase     * @return This object, allowing calls to methods in this class to be chained.
673a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase     */
674a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase    public ViewPropertyAnimator alphaBy(float value) {
675a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase        animatePropertyBy(ALPHA, value);
676a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase        return this;
677a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase    }
678a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase
679a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase    /**
680c1ca665827f0c34419a55c005254c1aaa0d58b40Chet Haase     * The View associated with this ViewPropertyAnimator will have its
681c1ca665827f0c34419a55c005254c1aaa0d58b40Chet Haase     * {@link View#setLayerType(int, android.graphics.Paint) layer type} set to
682cb150fe9e6495256019b02be51e736679b57c1b5Chet Haase     * {@link View#LAYER_TYPE_HARDWARE} for the duration of the next animation.
683cb150fe9e6495256019b02be51e736679b57c1b5Chet Haase     * As stated in the documentation for {@link View#LAYER_TYPE_HARDWARE},
684cb150fe9e6495256019b02be51e736679b57c1b5Chet Haase     * the actual type of layer used internally depends on the runtime situation of the
685cb150fe9e6495256019b02be51e736679b57c1b5Chet Haase     * view. If the activity and this view are hardware-accelerated, then the layer will be
686cb150fe9e6495256019b02be51e736679b57c1b5Chet Haase     * accelerated as well. If the activity or the view is not accelerated, then the layer will
687cb150fe9e6495256019b02be51e736679b57c1b5Chet Haase     * effectively be the same as {@link View#LAYER_TYPE_SOFTWARE}.
688cb150fe9e6495256019b02be51e736679b57c1b5Chet Haase     *
689cb150fe9e6495256019b02be51e736679b57c1b5Chet Haase     * <p>This state is not persistent, either on the View or on this ViewPropertyAnimator: the
690cb150fe9e6495256019b02be51e736679b57c1b5Chet Haase     * layer type of the View will be restored when the animation ends to what it was when this
691cb150fe9e6495256019b02be51e736679b57c1b5Chet Haase     * method was called, and this setting on ViewPropertyAnimator is only valid for the next
692cb150fe9e6495256019b02be51e736679b57c1b5Chet Haase     * animation. Note that calling this method and then independently setting the layer type of
693cb150fe9e6495256019b02be51e736679b57c1b5Chet Haase     * the View (by a direct call to {@link View#setLayerType(int, android.graphics.Paint)}) will
694cb150fe9e6495256019b02be51e736679b57c1b5Chet Haase     * result in some inconsistency, including having the layer type restored to its pre-withLayer()
695cb150fe9e6495256019b02be51e736679b57c1b5Chet Haase     * value when the animation ends.</p>
696c1ca665827f0c34419a55c005254c1aaa0d58b40Chet Haase     *
697c1ca665827f0c34419a55c005254c1aaa0d58b40Chet Haase     * @see View#setLayerType(int, android.graphics.Paint)
698c1ca665827f0c34419a55c005254c1aaa0d58b40Chet Haase     * @return This object, allowing calls to methods in this class to be chained.
699c1ca665827f0c34419a55c005254c1aaa0d58b40Chet Haase     */
700c1ca665827f0c34419a55c005254c1aaa0d58b40Chet Haase    public ViewPropertyAnimator withLayer() {
701c1ca665827f0c34419a55c005254c1aaa0d58b40Chet Haase         mPendingSetupAction= new Runnable() {
702c1ca665827f0c34419a55c005254c1aaa0d58b40Chet Haase            @Override
703c1ca665827f0c34419a55c005254c1aaa0d58b40Chet Haase            public void run() {
704c1ca665827f0c34419a55c005254c1aaa0d58b40Chet Haase                mView.setLayerType(View.LAYER_TYPE_HARDWARE, null);
7055fd37236dff9ab4d605ddac873d6a353f74838b5Chet Haase                if (mView.isAttachedToWindow()) {
7065fd37236dff9ab4d605ddac873d6a353f74838b5Chet Haase                    mView.buildLayer();
7075fd37236dff9ab4d605ddac873d6a353f74838b5Chet Haase                }
708c1ca665827f0c34419a55c005254c1aaa0d58b40Chet Haase            }
709c1ca665827f0c34419a55c005254c1aaa0d58b40Chet Haase        };
710c1ca665827f0c34419a55c005254c1aaa0d58b40Chet Haase        final int currentLayerType = mView.getLayerType();
711c1ca665827f0c34419a55c005254c1aaa0d58b40Chet Haase        mPendingCleanupAction = new Runnable() {
712c1ca665827f0c34419a55c005254c1aaa0d58b40Chet Haase            @Override
713c1ca665827f0c34419a55c005254c1aaa0d58b40Chet Haase            public void run() {
714c1ca665827f0c34419a55c005254c1aaa0d58b40Chet Haase                mView.setLayerType(currentLayerType, null);
715c1ca665827f0c34419a55c005254c1aaa0d58b40Chet Haase            }
716c1ca665827f0c34419a55c005254c1aaa0d58b40Chet Haase        };
717c1ca665827f0c34419a55c005254c1aaa0d58b40Chet Haase        if (mAnimatorSetupMap == null) {
718c1ca665827f0c34419a55c005254c1aaa0d58b40Chet Haase            mAnimatorSetupMap = new HashMap<Animator, Runnable>();
719c1ca665827f0c34419a55c005254c1aaa0d58b40Chet Haase        }
720c1ca665827f0c34419a55c005254c1aaa0d58b40Chet Haase        if (mAnimatorCleanupMap == null) {
721c1ca665827f0c34419a55c005254c1aaa0d58b40Chet Haase            mAnimatorCleanupMap = new HashMap<Animator, Runnable>();
722c1ca665827f0c34419a55c005254c1aaa0d58b40Chet Haase        }
723c1ca665827f0c34419a55c005254c1aaa0d58b40Chet Haase
724c1ca665827f0c34419a55c005254c1aaa0d58b40Chet Haase        return this;
725c1ca665827f0c34419a55c005254c1aaa0d58b40Chet Haase    }
726c1ca665827f0c34419a55c005254c1aaa0d58b40Chet Haase
727c1ca665827f0c34419a55c005254c1aaa0d58b40Chet Haase    /**
728c1ca665827f0c34419a55c005254c1aaa0d58b40Chet Haase     * Specifies an action to take place when the next animation runs. If there is a
729c1ca665827f0c34419a55c005254c1aaa0d58b40Chet Haase     * {@link #setStartDelay(long) startDelay} set on this ViewPropertyAnimator, then the
730c1ca665827f0c34419a55c005254c1aaa0d58b40Chet Haase     * action will run after that startDelay expires, when the actual animation begins.
731c1ca665827f0c34419a55c005254c1aaa0d58b40Chet Haase     * This method, along with {@link #withEndAction(Runnable)}, is intended to help facilitate
732c1ca665827f0c34419a55c005254c1aaa0d58b40Chet Haase     * choreographing ViewPropertyAnimator animations with other animations or actions
733c1ca665827f0c34419a55c005254c1aaa0d58b40Chet Haase     * in the application.
734c1ca665827f0c34419a55c005254c1aaa0d58b40Chet Haase     *
735c1ca665827f0c34419a55c005254c1aaa0d58b40Chet Haase     * @param runnable The action to run when the next animation starts.
736c1ca665827f0c34419a55c005254c1aaa0d58b40Chet Haase     * @return This object, allowing calls to methods in this class to be chained.
737c1ca665827f0c34419a55c005254c1aaa0d58b40Chet Haase     */
738c1ca665827f0c34419a55c005254c1aaa0d58b40Chet Haase    public ViewPropertyAnimator withStartAction(Runnable runnable) {
739c1ca665827f0c34419a55c005254c1aaa0d58b40Chet Haase        mPendingOnStartAction = runnable;
740c1ca665827f0c34419a55c005254c1aaa0d58b40Chet Haase        if (runnable != null && mAnimatorOnStartMap == null) {
741c1ca665827f0c34419a55c005254c1aaa0d58b40Chet Haase            mAnimatorOnStartMap = new HashMap<Animator, Runnable>();
742c1ca665827f0c34419a55c005254c1aaa0d58b40Chet Haase        }
743c1ca665827f0c34419a55c005254c1aaa0d58b40Chet Haase        return this;
744c1ca665827f0c34419a55c005254c1aaa0d58b40Chet Haase    }
745c1ca665827f0c34419a55c005254c1aaa0d58b40Chet Haase
746c1ca665827f0c34419a55c005254c1aaa0d58b40Chet Haase    /**
747c1ca665827f0c34419a55c005254c1aaa0d58b40Chet Haase     * Specifies an action to take place when the next animation ends. The action is only
748c1ca665827f0c34419a55c005254c1aaa0d58b40Chet Haase     * run if the animation ends normally; if the ViewPropertyAnimator is canceled during
749c1ca665827f0c34419a55c005254c1aaa0d58b40Chet Haase     * that animation, the runnable will not run.
750c1ca665827f0c34419a55c005254c1aaa0d58b40Chet Haase     * This method, along with {@link #withStartAction(Runnable)}, is intended to help facilitate
751c1ca665827f0c34419a55c005254c1aaa0d58b40Chet Haase     * choreographing ViewPropertyAnimator animations with other animations or actions
752c1ca665827f0c34419a55c005254c1aaa0d58b40Chet Haase     * in the application.
753c1ca665827f0c34419a55c005254c1aaa0d58b40Chet Haase     *
754c1ca665827f0c34419a55c005254c1aaa0d58b40Chet Haase     * <p>For example, the following code animates a view to x=200 and then back to 0:</p>
755c1ca665827f0c34419a55c005254c1aaa0d58b40Chet Haase     * <pre>
756c1ca665827f0c34419a55c005254c1aaa0d58b40Chet Haase     *     Runnable endAction = new Runnable() {
757c1ca665827f0c34419a55c005254c1aaa0d58b40Chet Haase     *         public void run() {
758c1ca665827f0c34419a55c005254c1aaa0d58b40Chet Haase     *             view.animate().x(0);
759c1ca665827f0c34419a55c005254c1aaa0d58b40Chet Haase     *         }
760c1ca665827f0c34419a55c005254c1aaa0d58b40Chet Haase     *     };
7618ee2a70f08f54314d3ff0cd571a7ea9337065389Robert Ly     *     view.animate().x(200).withEndAction(endAction);
762c1ca665827f0c34419a55c005254c1aaa0d58b40Chet Haase     * </pre>
763c1ca665827f0c34419a55c005254c1aaa0d58b40Chet Haase     *
764c1ca665827f0c34419a55c005254c1aaa0d58b40Chet Haase     * @param runnable The action to run when the next animation ends.
765c1ca665827f0c34419a55c005254c1aaa0d58b40Chet Haase     * @return This object, allowing calls to methods in this class to be chained.
766c1ca665827f0c34419a55c005254c1aaa0d58b40Chet Haase     */
767c1ca665827f0c34419a55c005254c1aaa0d58b40Chet Haase    public ViewPropertyAnimator withEndAction(Runnable runnable) {
768c1ca665827f0c34419a55c005254c1aaa0d58b40Chet Haase        mPendingOnEndAction = runnable;
769c1ca665827f0c34419a55c005254c1aaa0d58b40Chet Haase        if (runnable != null && mAnimatorOnEndMap == null) {
770c1ca665827f0c34419a55c005254c1aaa0d58b40Chet Haase            mAnimatorOnEndMap = new HashMap<Animator, Runnable>();
771c1ca665827f0c34419a55c005254c1aaa0d58b40Chet Haase        }
772c1ca665827f0c34419a55c005254c1aaa0d58b40Chet Haase        return this;
773c1ca665827f0c34419a55c005254c1aaa0d58b40Chet Haase    }
774c1ca665827f0c34419a55c005254c1aaa0d58b40Chet Haase
775c1ca665827f0c34419a55c005254c1aaa0d58b40Chet Haase    /**
776a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase     * Starts the underlying Animator for a set of properties. We use a single animator that
777a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase     * simply runs from 0 to 1, and then use that fractional value to set each property
778a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase     * value accordingly.
779a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase     */
780a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase    private void startAnimation() {
781563d4f2d461d264457b7e7068e2fc7b9b0bcafb3Chet Haase        mView.setHasTransientState(true);
782a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase        ValueAnimator animator = ValueAnimator.ofFloat(1.0f);
783a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase        ArrayList<NameValuesHolder> nameValueList =
784a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase                (ArrayList<NameValuesHolder>) mPendingAnimations.clone();
785a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase        mPendingAnimations.clear();
786a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase        int propertyMask = 0;
787a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase        int propertyCount = nameValueList.size();
788a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase        for (int i = 0; i < propertyCount; ++i) {
789a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase            NameValuesHolder nameValuesHolder = nameValueList.get(i);
790a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase            propertyMask |= nameValuesHolder.mNameConstant;
791a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase        }
792a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase        mAnimatorMap.put(animator, new PropertyBundle(propertyMask, nameValueList));
793c1ca665827f0c34419a55c005254c1aaa0d58b40Chet Haase        if (mPendingSetupAction != null) {
794c1ca665827f0c34419a55c005254c1aaa0d58b40Chet Haase            mAnimatorSetupMap.put(animator, mPendingSetupAction);
795c1ca665827f0c34419a55c005254c1aaa0d58b40Chet Haase            mPendingSetupAction = null;
796c1ca665827f0c34419a55c005254c1aaa0d58b40Chet Haase        }
797c1ca665827f0c34419a55c005254c1aaa0d58b40Chet Haase        if (mPendingCleanupAction != null) {
798c1ca665827f0c34419a55c005254c1aaa0d58b40Chet Haase            mAnimatorCleanupMap.put(animator, mPendingCleanupAction);
799c1ca665827f0c34419a55c005254c1aaa0d58b40Chet Haase            mPendingCleanupAction = null;
800c1ca665827f0c34419a55c005254c1aaa0d58b40Chet Haase        }
801c1ca665827f0c34419a55c005254c1aaa0d58b40Chet Haase        if (mPendingOnStartAction != null) {
802c1ca665827f0c34419a55c005254c1aaa0d58b40Chet Haase            mAnimatorOnStartMap.put(animator, mPendingOnStartAction);
803c1ca665827f0c34419a55c005254c1aaa0d58b40Chet Haase            mPendingOnStartAction = null;
804c1ca665827f0c34419a55c005254c1aaa0d58b40Chet Haase        }
805c1ca665827f0c34419a55c005254c1aaa0d58b40Chet Haase        if (mPendingOnEndAction != null) {
806c1ca665827f0c34419a55c005254c1aaa0d58b40Chet Haase            mAnimatorOnEndMap.put(animator, mPendingOnEndAction);
807c1ca665827f0c34419a55c005254c1aaa0d58b40Chet Haase            mPendingOnEndAction = null;
808c1ca665827f0c34419a55c005254c1aaa0d58b40Chet Haase        }
809a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase        animator.addUpdateListener(mAnimatorEventListener);
810a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase        animator.addListener(mAnimatorEventListener);
811cbbd93ae701b9af2e5054d59286bdbf6275c2838Chet Haase        if (mStartDelaySet) {
812cbbd93ae701b9af2e5054d59286bdbf6275c2838Chet Haase            animator.setStartDelay(mStartDelay);
813cbbd93ae701b9af2e5054d59286bdbf6275c2838Chet Haase        }
814a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase        if (mDurationSet) {
815a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase            animator.setDuration(mDuration);
816a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase        }
817a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase        if (mInterpolatorSet) {
818a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase            animator.setInterpolator(mInterpolator);
819a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase        }
820a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase        animator.start();
821a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase    }
822a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase
823a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase    /**
824a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase     * Utility function, called by the various x(), y(), etc. methods. This stores the
825d666cf320db4134938f72b0ffe18212997f8c8d8Chet Haase     * constant name for the property along with the from/delta values that will be used to
826a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase     * calculate and set the property during the animation. This structure is added to the
827a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase     * pending animations, awaiting the eventual start() of the underlying animator. A
828a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase     * Runnable is posted to start the animation, and any pending such Runnable is canceled
829a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase     * (which enables us to end up starting just one animator for all of the properties
830a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase     * specified at one time).
831a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase     *
832a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase     * @param constantName The specifier for the property being animated
833a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase     * @param toValue The value to which the property will animate
834a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase     */
835a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase    private void animateProperty(int constantName, float toValue) {
836a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase        float fromValue = getValue(constantName);
837a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase        float deltaValue = toValue - fromValue;
838a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase        animatePropertyBy(constantName, fromValue, deltaValue);
839a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase    }
840a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase
841a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase    /**
842a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase     * Utility function, called by the various xBy(), yBy(), etc. methods. This method is
843a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase     * just like animateProperty(), except the value is an offset from the property's
844a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase     * current value, instead of an absolute "to" value.
845a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase     *
846a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase     * @param constantName The specifier for the property being animated
847a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase     * @param byValue The amount by which the property will change
848a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase     */
849a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase    private void animatePropertyBy(int constantName, float byValue) {
850a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase        float fromValue = getValue(constantName);
851a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase        animatePropertyBy(constantName, fromValue, byValue);
852a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase    }
853a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase
854a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase    /**
855d666cf320db4134938f72b0ffe18212997f8c8d8Chet Haase     * Utility function, called by animateProperty() and animatePropertyBy(), which handles the
856a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase     * details of adding a pending animation and posting the request to start the animation.
857a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase     *
858a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase     * @param constantName The specifier for the property being animated
859d666cf320db4134938f72b0ffe18212997f8c8d8Chet Haase     * @param startValue The starting value of the property
860a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase     * @param byValue The amount by which the property will change
861a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase     */
862d666cf320db4134938f72b0ffe18212997f8c8d8Chet Haase    private void animatePropertyBy(int constantName, float startValue, float byValue) {
863ba592d200390d89723682f1a7e40d308d7804b36Chet Haase        // First, cancel any existing animations on this property
864ba592d200390d89723682f1a7e40d308d7804b36Chet Haase        if (mAnimatorMap.size() > 0) {
865ba592d200390d89723682f1a7e40d308d7804b36Chet Haase            Animator animatorToCancel = null;
866ba592d200390d89723682f1a7e40d308d7804b36Chet Haase            Set<Animator> animatorSet = mAnimatorMap.keySet();
867ba592d200390d89723682f1a7e40d308d7804b36Chet Haase            for (Animator runningAnim : animatorSet) {
868ba592d200390d89723682f1a7e40d308d7804b36Chet Haase                PropertyBundle bundle = mAnimatorMap.get(runningAnim);
869ba592d200390d89723682f1a7e40d308d7804b36Chet Haase                if (bundle.cancel(constantName)) {
870ba592d200390d89723682f1a7e40d308d7804b36Chet Haase                    // property was canceled - cancel the animation if it's now empty
871ba592d200390d89723682f1a7e40d308d7804b36Chet Haase                    // Note that it's safe to break out here because every new animation
872ba592d200390d89723682f1a7e40d308d7804b36Chet Haase                    // on a property will cancel a previous animation on that property, so
873ba592d200390d89723682f1a7e40d308d7804b36Chet Haase                    // there can only ever be one such animation running.
874ba592d200390d89723682f1a7e40d308d7804b36Chet Haase                    if (bundle.mPropertyMask == NONE) {
8758d5f808f70c1d47437eaf49234c1b3a23c244040Chet Haase                        // the animation is no longer changing anything - cancel it
876ba592d200390d89723682f1a7e40d308d7804b36Chet Haase                        animatorToCancel = runningAnim;
877ba592d200390d89723682f1a7e40d308d7804b36Chet Haase                        break;
878ba592d200390d89723682f1a7e40d308d7804b36Chet Haase                    }
879ba592d200390d89723682f1a7e40d308d7804b36Chet Haase                }
880ba592d200390d89723682f1a7e40d308d7804b36Chet Haase            }
881ba592d200390d89723682f1a7e40d308d7804b36Chet Haase            if (animatorToCancel != null) {
882ba592d200390d89723682f1a7e40d308d7804b36Chet Haase                animatorToCancel.cancel();
883ba592d200390d89723682f1a7e40d308d7804b36Chet Haase            }
884ba592d200390d89723682f1a7e40d308d7804b36Chet Haase        }
885ba592d200390d89723682f1a7e40d308d7804b36Chet Haase
886a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase        NameValuesHolder nameValuePair = new NameValuesHolder(constantName, startValue, byValue);
887a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase        mPendingAnimations.add(nameValuePair);
8883a000a52d6863bd1c6c9822a9cfd83e00f3aaf79Chet Haase        mView.removeCallbacks(mAnimationStarter);
889dcfbd6a2c99fa9f77c8ffec81c36d28e21ac18a7Chet Haase        mView.postOnAnimation(mAnimationStarter);
890a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase    }
891a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase
892a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase    /**
893a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase     * This method handles setting the property values directly in the View object's fields.
894a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase     * propertyConstant tells it which property should be set, value is the value to set
895a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase     * the property to.
896a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase     *
897a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase     * @param propertyConstant The property to be set
898a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase     * @param value The value to set the property to
899a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase     */
900a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase    private void setValue(int propertyConstant, float value) {
901ddb715b238c098d8b561a44b9687f0bc67a4c141Dianne Hackborn        final View.TransformationInfo info = mView.mTransformationInfo;
9021271e2cc80b01d577e9db339459ef0222bb9320dChet Haase        final DisplayList displayList = mView.mDisplayList;
903a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase        switch (propertyConstant) {
904a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase            case TRANSLATION_X:
905ddb715b238c098d8b561a44b9687f0bc67a4c141Dianne Hackborn                info.mTranslationX = value;
906db8c9a6a4d9bf8c39f834b25611926caf21380f6Chet Haase                if (displayList != null) displayList.setTranslationX(value);
907a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase                break;
908a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase            case TRANSLATION_Y:
909ddb715b238c098d8b561a44b9687f0bc67a4c141Dianne Hackborn                info.mTranslationY = value;
910db8c9a6a4d9bf8c39f834b25611926caf21380f6Chet Haase                if (displayList != null) displayList.setTranslationY(value);
911a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase                break;
912a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase            case ROTATION:
913ddb715b238c098d8b561a44b9687f0bc67a4c141Dianne Hackborn                info.mRotation = value;
914db8c9a6a4d9bf8c39f834b25611926caf21380f6Chet Haase                if (displayList != null) displayList.setRotation(value);
915a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase                break;
916a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase            case ROTATION_X:
917ddb715b238c098d8b561a44b9687f0bc67a4c141Dianne Hackborn                info.mRotationX = value;
918db8c9a6a4d9bf8c39f834b25611926caf21380f6Chet Haase                if (displayList != null) displayList.setRotationX(value);
919a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase                break;
920a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase            case ROTATION_Y:
921ddb715b238c098d8b561a44b9687f0bc67a4c141Dianne Hackborn                info.mRotationY = value;
922db8c9a6a4d9bf8c39f834b25611926caf21380f6Chet Haase                if (displayList != null) displayList.setRotationY(value);
923a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase                break;
924a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase            case SCALE_X:
925ddb715b238c098d8b561a44b9687f0bc67a4c141Dianne Hackborn                info.mScaleX = value;
926db8c9a6a4d9bf8c39f834b25611926caf21380f6Chet Haase                if (displayList != null) displayList.setScaleX(value);
927a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase                break;
928a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase            case SCALE_Y:
929ddb715b238c098d8b561a44b9687f0bc67a4c141Dianne Hackborn                info.mScaleY = value;
930db8c9a6a4d9bf8c39f834b25611926caf21380f6Chet Haase                if (displayList != null) displayList.setScaleY(value);
931a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase                break;
932a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase            case X:
933ddb715b238c098d8b561a44b9687f0bc67a4c141Dianne Hackborn                info.mTranslationX = value - mView.mLeft;
934db8c9a6a4d9bf8c39f834b25611926caf21380f6Chet Haase                if (displayList != null) displayList.setTranslationX(value - mView.mLeft);
935a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase                break;
936a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase            case Y:
937ddb715b238c098d8b561a44b9687f0bc67a4c141Dianne Hackborn                info.mTranslationY = value - mView.mTop;
938db8c9a6a4d9bf8c39f834b25611926caf21380f6Chet Haase                if (displayList != null) displayList.setTranslationY(value - mView.mTop);
939a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase                break;
940a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase            case ALPHA:
941ddb715b238c098d8b561a44b9687f0bc67a4c141Dianne Hackborn                info.mAlpha = value;
942db8c9a6a4d9bf8c39f834b25611926caf21380f6Chet Haase                if (displayList != null) displayList.setAlpha(value);
943a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase                break;
944a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase        }
945a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase    }
946a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase
947a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase    /**
948a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase     * This method gets the value of the named property from the View object.
949a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase     *
950a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase     * @param propertyConstant The property whose value should be returned
951a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase     * @return float The value of the named property
952a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase     */
953a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase    private float getValue(int propertyConstant) {
954ddb715b238c098d8b561a44b9687f0bc67a4c141Dianne Hackborn        final View.TransformationInfo info = mView.mTransformationInfo;
955a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase        switch (propertyConstant) {
956a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase            case TRANSLATION_X:
957ddb715b238c098d8b561a44b9687f0bc67a4c141Dianne Hackborn                return info.mTranslationX;
958a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase            case TRANSLATION_Y:
959ddb715b238c098d8b561a44b9687f0bc67a4c141Dianne Hackborn                return info.mTranslationY;
960a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase            case ROTATION:
961ddb715b238c098d8b561a44b9687f0bc67a4c141Dianne Hackborn                return info.mRotation;
962a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase            case ROTATION_X:
963ddb715b238c098d8b561a44b9687f0bc67a4c141Dianne Hackborn                return info.mRotationX;
964a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase            case ROTATION_Y:
965ddb715b238c098d8b561a44b9687f0bc67a4c141Dianne Hackborn                return info.mRotationY;
966a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase            case SCALE_X:
967ddb715b238c098d8b561a44b9687f0bc67a4c141Dianne Hackborn                return info.mScaleX;
968a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase            case SCALE_Y:
969ddb715b238c098d8b561a44b9687f0bc67a4c141Dianne Hackborn                return info.mScaleY;
970a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase            case X:
971ddb715b238c098d8b561a44b9687f0bc67a4c141Dianne Hackborn                return mView.mLeft + info.mTranslationX;
972a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase            case Y:
973ddb715b238c098d8b561a44b9687f0bc67a4c141Dianne Hackborn                return mView.mTop + info.mTranslationY;
974a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase            case ALPHA:
975ddb715b238c098d8b561a44b9687f0bc67a4c141Dianne Hackborn                return info.mAlpha;
976a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase        }
977a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase        return 0;
978a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase    }
979a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase
980a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase    /**
981a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase     * Utility class that handles the various Animator events. The only ones we care
982a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase     * about are the end event (which we use to clean up the animator map when an animator
983a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase     * finishes) and the update event (which we use to calculate the current value of each
984a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase     * property and then set it on the view object).
985a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase     */
986a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase    private class AnimatorEventListener
987a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase            implements Animator.AnimatorListener, ValueAnimator.AnimatorUpdateListener {
988a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase        @Override
989a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase        public void onAnimationStart(Animator animation) {
990c1ca665827f0c34419a55c005254c1aaa0d58b40Chet Haase            if (mAnimatorSetupMap != null) {
991c1ca665827f0c34419a55c005254c1aaa0d58b40Chet Haase                Runnable r = mAnimatorSetupMap.get(animation);
992c1ca665827f0c34419a55c005254c1aaa0d58b40Chet Haase                if (r != null) {
993c1ca665827f0c34419a55c005254c1aaa0d58b40Chet Haase                    r.run();
994c1ca665827f0c34419a55c005254c1aaa0d58b40Chet Haase                }
995c1ca665827f0c34419a55c005254c1aaa0d58b40Chet Haase                mAnimatorSetupMap.remove(animation);
996c1ca665827f0c34419a55c005254c1aaa0d58b40Chet Haase            }
997c1ca665827f0c34419a55c005254c1aaa0d58b40Chet Haase            if (mAnimatorOnStartMap != null) {
998c1ca665827f0c34419a55c005254c1aaa0d58b40Chet Haase                Runnable r = mAnimatorOnStartMap.get(animation);
999c1ca665827f0c34419a55c005254c1aaa0d58b40Chet Haase                if (r != null) {
1000c1ca665827f0c34419a55c005254c1aaa0d58b40Chet Haase                    r.run();
1001c1ca665827f0c34419a55c005254c1aaa0d58b40Chet Haase                }
1002c1ca665827f0c34419a55c005254c1aaa0d58b40Chet Haase                mAnimatorOnStartMap.remove(animation);
1003c1ca665827f0c34419a55c005254c1aaa0d58b40Chet Haase            }
1004a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase            if (mListener != null) {
1005a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase                mListener.onAnimationStart(animation);
1006a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase            }
1007a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase        }
1008a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase
1009a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase        @Override
1010a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase        public void onAnimationCancel(Animator animation) {
1011a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase            if (mListener != null) {
1012a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase                mListener.onAnimationCancel(animation);
1013a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase            }
1014c1ca665827f0c34419a55c005254c1aaa0d58b40Chet Haase            if (mAnimatorOnEndMap != null) {
1015c1ca665827f0c34419a55c005254c1aaa0d58b40Chet Haase                mAnimatorOnEndMap.remove(animation);
1016c1ca665827f0c34419a55c005254c1aaa0d58b40Chet Haase            }
1017a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase        }
1018a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase
1019a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase        @Override
1020a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase        public void onAnimationRepeat(Animator animation) {
1021a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase            if (mListener != null) {
1022a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase                mListener.onAnimationRepeat(animation);
1023a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase            }
1024a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase        }
1025a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase
1026a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase        @Override
1027a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase        public void onAnimationEnd(Animator animation) {
1028563d4f2d461d264457b7e7068e2fc7b9b0bcafb3Chet Haase            mView.setHasTransientState(false);
1029a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase            if (mListener != null) {
1030a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase                mListener.onAnimationEnd(animation);
1031a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase            }
1032c1ca665827f0c34419a55c005254c1aaa0d58b40Chet Haase            if (mAnimatorOnEndMap != null) {
1033c1ca665827f0c34419a55c005254c1aaa0d58b40Chet Haase                Runnable r = mAnimatorOnEndMap.get(animation);
1034c1ca665827f0c34419a55c005254c1aaa0d58b40Chet Haase                if (r != null) {
1035c1ca665827f0c34419a55c005254c1aaa0d58b40Chet Haase                    r.run();
1036c1ca665827f0c34419a55c005254c1aaa0d58b40Chet Haase                }
1037c1ca665827f0c34419a55c005254c1aaa0d58b40Chet Haase                mAnimatorOnEndMap.remove(animation);
1038c1ca665827f0c34419a55c005254c1aaa0d58b40Chet Haase            }
1039c1ca665827f0c34419a55c005254c1aaa0d58b40Chet Haase            if (mAnimatorCleanupMap != null) {
1040c1ca665827f0c34419a55c005254c1aaa0d58b40Chet Haase                Runnable r = mAnimatorCleanupMap.get(animation);
1041c1ca665827f0c34419a55c005254c1aaa0d58b40Chet Haase                if (r != null) {
1042c1ca665827f0c34419a55c005254c1aaa0d58b40Chet Haase                    r.run();
1043c1ca665827f0c34419a55c005254c1aaa0d58b40Chet Haase                }
1044c1ca665827f0c34419a55c005254c1aaa0d58b40Chet Haase                mAnimatorCleanupMap.remove(animation);
1045c1ca665827f0c34419a55c005254c1aaa0d58b40Chet Haase            }
1046a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase            mAnimatorMap.remove(animation);
1047a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase        }
1048a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase
1049a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase        /**
1050a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase         * Calculate the current value for each property and set it on the view. Invalidate
1051a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase         * the view object appropriately, depending on which properties are being animated.
1052a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase         *
1053a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase         * @param animation The animator associated with the properties that need to be
1054a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase         * set. This animator holds the animation fraction which we will use to calculate
1055a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase         * the current value of each property.
1056a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase         */
1057a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase        @Override
1058a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase        public void onAnimationUpdate(ValueAnimator animation) {
10590c6d83cc5625f967eb2e23cc7c232874cd9e60f9Chet Haase            PropertyBundle propertyBundle = mAnimatorMap.get(animation);
10600c6d83cc5625f967eb2e23cc7c232874cd9e60f9Chet Haase            if (propertyBundle == null) {
10610c6d83cc5625f967eb2e23cc7c232874cd9e60f9Chet Haase                // Shouldn't happen, but just to play it safe
10620c6d83cc5625f967eb2e23cc7c232874cd9e60f9Chet Haase                return;
10630c6d83cc5625f967eb2e23cc7c232874cd9e60f9Chet Haase            }
10641271e2cc80b01d577e9db339459ef0222bb9320dChet Haase            boolean useDisplayListProperties = mView.mDisplayList != null;
10659d1992deaeb3d60d5928f05b649a2cc654ba98a3Chet Haase
1066a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase            // alpha requires slightly different treatment than the other (transform) properties.
1067a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase            // The logic in setAlpha() is not simply setting mAlpha, plus the invalidation
1068a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase            // logic is dependent on how the view handles an internal call to onSetAlpha().
1069a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase            // We track what kinds of properties are set, and how alpha is handled when it is
1070a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase            // set, and perform the invalidation steps appropriately.
1071a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase            boolean alphaHandled = false;
10729d1992deaeb3d60d5928f05b649a2cc654ba98a3Chet Haase            if (!useDisplayListProperties) {
10739d1992deaeb3d60d5928f05b649a2cc654ba98a3Chet Haase                mView.invalidateParentCaches();
10749d1992deaeb3d60d5928f05b649a2cc654ba98a3Chet Haase            }
1075a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase            float fraction = animation.getAnimatedFraction();
1076a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase            int propertyMask = propertyBundle.mPropertyMask;
1077a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase            if ((propertyMask & TRANSFORM_MASK) != 0) {
10789d1992deaeb3d60d5928f05b649a2cc654ba98a3Chet Haase                mView.invalidateViewProperty(false, false);
1079a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase            }
1080a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase            ArrayList<NameValuesHolder> valueList = propertyBundle.mNameValuesHolder;
1081a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase            if (valueList != null) {
1082a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase                int count = valueList.size();
1083a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase                for (int i = 0; i < count; ++i) {
1084a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase                    NameValuesHolder values = valueList.get(i);
1085a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase                    float value = values.mFromValue + fraction * values.mDeltaValue;
1086a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase                    if (values.mNameConstant == ALPHA) {
1087a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase                        alphaHandled = mView.setAlphaNoInvalidation(value);
1088a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase                    } else {
1089a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase                        setValue(values.mNameConstant, value);
1090a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase                    }
1091a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase                }
1092a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase            }
1093a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase            if ((propertyMask & TRANSFORM_MASK) != 0) {
1094ddb715b238c098d8b561a44b9687f0bc67a4c141Dianne Hackborn                mView.mTransformationInfo.mMatrixDirty = true;
10959d1992deaeb3d60d5928f05b649a2cc654ba98a3Chet Haase                if (!useDisplayListProperties) {
10964702a856973a553deb82f71b1d3b6c3db5dbf4baDianne Hackborn                    mView.mPrivateFlags |= View.PFLAG_DRAWN; // force another invalidation
10979d1992deaeb3d60d5928f05b649a2cc654ba98a3Chet Haase                }
1098a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase            }
1099a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase            // invalidate(false) in all cases except if alphaHandled gets set to true
1100a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase            // via the call to setAlphaNoInvalidation(), above
11019d1992deaeb3d60d5928f05b649a2cc654ba98a3Chet Haase            if (alphaHandled) {
11029d1992deaeb3d60d5928f05b649a2cc654ba98a3Chet Haase                mView.invalidate(true);
11039d1992deaeb3d60d5928f05b649a2cc654ba98a3Chet Haase            } else {
11049d1992deaeb3d60d5928f05b649a2cc654ba98a3Chet Haase                mView.invalidateViewProperty(false, false);
11059d1992deaeb3d60d5928f05b649a2cc654ba98a3Chet Haase            }
110687f4ae67c86c7044253b3e1bcec6956a8c8bf017Chet Haase            if (mUpdateListener != null) {
110787f4ae67c86c7044253b3e1bcec6956a8c8bf017Chet Haase                mUpdateListener.onAnimationUpdate(animation);
110887f4ae67c86c7044253b3e1bcec6956a8c8bf017Chet Haase            }
1109a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase        }
1110a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase    }
1111a00f3865f55c5c9cb74510ee2b239d101230133cChet Haase}
1112