1d7d27e9ebe5c7325e67e1a8af265378bd2056cadChet Haase/* 2d7d27e9ebe5c7325e67e1a8af265378bd2056cadChet Haase * Copyright (C) 2014 The Android Open Source Project 3d7d27e9ebe5c7325e67e1a8af265378bd2056cadChet Haase * 4d7d27e9ebe5c7325e67e1a8af265378bd2056cadChet Haase * Licensed under the Apache License, Version 2.0 (the "License"); 5d7d27e9ebe5c7325e67e1a8af265378bd2056cadChet Haase * you may not use this file except in compliance with the License. 6d7d27e9ebe5c7325e67e1a8af265378bd2056cadChet Haase * You may obtain a copy of the License at 7d7d27e9ebe5c7325e67e1a8af265378bd2056cadChet Haase * 8d7d27e9ebe5c7325e67e1a8af265378bd2056cadChet Haase * http://www.apache.org/licenses/LICENSE-2.0 9d7d27e9ebe5c7325e67e1a8af265378bd2056cadChet Haase * 10d7d27e9ebe5c7325e67e1a8af265378bd2056cadChet Haase * Unless required by applicable law or agreed to in writing, software 11d7d27e9ebe5c7325e67e1a8af265378bd2056cadChet Haase * distributed under the License is distributed on an "AS IS" BASIS, 12d7d27e9ebe5c7325e67e1a8af265378bd2056cadChet Haase * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13d7d27e9ebe5c7325e67e1a8af265378bd2056cadChet Haase * See the License for the specific language governing permissions and 14d7d27e9ebe5c7325e67e1a8af265378bd2056cadChet Haase * limitations under the License. 15d7d27e9ebe5c7325e67e1a8af265378bd2056cadChet Haase */ 16d7d27e9ebe5c7325e67e1a8af265378bd2056cadChet Haasepackage android.support.v4.view; 17d7d27e9ebe5c7325e67e1a8af265378bd2056cadChet Haase 18a6b67f8cbb80323786f7e5d9db442f080e242d76Aurimas Liutikasimport android.animation.Animator; 19a6b67f8cbb80323786f7e5d9db442f080e242d76Aurimas Liutikasimport android.animation.AnimatorListenerAdapter; 20a6b67f8cbb80323786f7e5d9db442f080e242d76Aurimas Liutikasimport android.animation.ValueAnimator; 21bfd48d0521963754e04e407499ee9e278fe06c0fChris Banesimport android.os.Build; 22d7d27e9ebe5c7325e67e1a8af265378bd2056cadChet Haaseimport android.view.View; 23d7d27e9ebe5c7325e67e1a8af265378bd2056cadChet Haaseimport android.view.animation.Interpolator; 24d7d27e9ebe5c7325e67e1a8af265378bd2056cadChet Haase 25d7d27e9ebe5c7325e67e1a8af265378bd2056cadChet Haaseimport java.lang.ref.WeakReference; 26d7d27e9ebe5c7325e67e1a8af265378bd2056cadChet Haase 27c5847d13e40f5d52459f5c0dab32dc08f1a9a683Chris Banespublic final class ViewPropertyAnimatorCompat { 28d7d27e9ebe5c7325e67e1a8af265378bd2056cadChet Haase private static final String TAG = "ViewAnimatorCompat"; 29d7d27e9ebe5c7325e67e1a8af265378bd2056cadChet Haase private WeakReference<View> mView; 30552766fa685c63ad760c92239faaba12e6ad51f1Aurimas Liutikas Runnable mStartAction = null; 31552766fa685c63ad760c92239faaba12e6ad51f1Aurimas Liutikas Runnable mEndAction = null; 32552766fa685c63ad760c92239faaba12e6ad51f1Aurimas Liutikas int mOldLayerType = -1; 33ead7065c8e987fefca4d0d850d824fb7d7bce677Chet Haase // HACK ALERT! Choosing this id knowing that the framework does not use it anywhere 34ead7065c8e987fefca4d0d850d824fb7d7bce677Chet Haase // internally and apps should use ids higher than it 35ead7065c8e987fefca4d0d850d824fb7d7bce677Chet Haase static final int LISTENER_TAG_ID = 0x7e000000; 36ead7065c8e987fefca4d0d850d824fb7d7bce677Chet Haase 37d7d27e9ebe5c7325e67e1a8af265378bd2056cadChet Haase ViewPropertyAnimatorCompat(View view) { 38d7d27e9ebe5c7325e67e1a8af265378bd2056cadChet Haase mView = new WeakReference<View>(view); 39d7d27e9ebe5c7325e67e1a8af265378bd2056cadChet Haase } 40d7d27e9ebe5c7325e67e1a8af265378bd2056cadChet Haase 41a6b67f8cbb80323786f7e5d9db442f080e242d76Aurimas Liutikas static class ViewPropertyAnimatorListenerApi14 implements ViewPropertyAnimatorListener { 42a6b67f8cbb80323786f7e5d9db442f080e242d76Aurimas Liutikas ViewPropertyAnimatorCompat mVpa; 43a6b67f8cbb80323786f7e5d9db442f080e242d76Aurimas Liutikas boolean mAnimEndCalled; 44d7d27e9ebe5c7325e67e1a8af265378bd2056cadChet Haase 45a6b67f8cbb80323786f7e5d9db442f080e242d76Aurimas Liutikas ViewPropertyAnimatorListenerApi14(ViewPropertyAnimatorCompat vpa) { 46a6b67f8cbb80323786f7e5d9db442f080e242d76Aurimas Liutikas mVpa = vpa; 47d7d27e9ebe5c7325e67e1a8af265378bd2056cadChet Haase } 48d7d27e9ebe5c7325e67e1a8af265378bd2056cadChet Haase 49d7d27e9ebe5c7325e67e1a8af265378bd2056cadChet Haase @Override 50a6b67f8cbb80323786f7e5d9db442f080e242d76Aurimas Liutikas public void onAnimationStart(View view) { 51a6b67f8cbb80323786f7e5d9db442f080e242d76Aurimas Liutikas // Reset our end called flag, since this is a new animation... 52a6b67f8cbb80323786f7e5d9db442f080e242d76Aurimas Liutikas mAnimEndCalled = false; 53e322b8bcc717dfd663677ed5cb59c6d1c3cb27afChris Banes 54a6b67f8cbb80323786f7e5d9db442f080e242d76Aurimas Liutikas if (mVpa.mOldLayerType > -1) { 55a6b67f8cbb80323786f7e5d9db442f080e242d76Aurimas Liutikas view.setLayerType(View.LAYER_TYPE_HARDWARE, null); 56a6b67f8cbb80323786f7e5d9db442f080e242d76Aurimas Liutikas } 57a6b67f8cbb80323786f7e5d9db442f080e242d76Aurimas Liutikas if (mVpa.mStartAction != null) { 58a6b67f8cbb80323786f7e5d9db442f080e242d76Aurimas Liutikas Runnable startAction = mVpa.mStartAction; 59a6b67f8cbb80323786f7e5d9db442f080e242d76Aurimas Liutikas mVpa.mStartAction = null; 60a6b67f8cbb80323786f7e5d9db442f080e242d76Aurimas Liutikas startAction.run(); 61a6b67f8cbb80323786f7e5d9db442f080e242d76Aurimas Liutikas } 62a6b67f8cbb80323786f7e5d9db442f080e242d76Aurimas Liutikas Object listenerTag = view.getTag(LISTENER_TAG_ID); 63a6b67f8cbb80323786f7e5d9db442f080e242d76Aurimas Liutikas ViewPropertyAnimatorListener listener = null; 64a6b67f8cbb80323786f7e5d9db442f080e242d76Aurimas Liutikas if (listenerTag instanceof ViewPropertyAnimatorListener) { 65a6b67f8cbb80323786f7e5d9db442f080e242d76Aurimas Liutikas listener = (ViewPropertyAnimatorListener) listenerTag; 66a6b67f8cbb80323786f7e5d9db442f080e242d76Aurimas Liutikas } 67a6b67f8cbb80323786f7e5d9db442f080e242d76Aurimas Liutikas if (listener != null) { 68a6b67f8cbb80323786f7e5d9db442f080e242d76Aurimas Liutikas listener.onAnimationStart(view); 69a6b67f8cbb80323786f7e5d9db442f080e242d76Aurimas Liutikas } 70e322b8bcc717dfd663677ed5cb59c6d1c3cb27afChris Banes } 71e322b8bcc717dfd663677ed5cb59c6d1c3cb27afChris Banes 72e322b8bcc717dfd663677ed5cb59c6d1c3cb27afChris Banes @Override 73a6b67f8cbb80323786f7e5d9db442f080e242d76Aurimas Liutikas public void onAnimationEnd(View view) { 74a6b67f8cbb80323786f7e5d9db442f080e242d76Aurimas Liutikas if (mVpa.mOldLayerType > -1) { 75a6b67f8cbb80323786f7e5d9db442f080e242d76Aurimas Liutikas view.setLayerType(mVpa.mOldLayerType, null); 76a6b67f8cbb80323786f7e5d9db442f080e242d76Aurimas Liutikas mVpa.mOldLayerType = -1; 77ead7065c8e987fefca4d0d850d824fb7d7bce677Chet Haase } 78a6b67f8cbb80323786f7e5d9db442f080e242d76Aurimas Liutikas if (Build.VERSION.SDK_INT >= 16 || !mAnimEndCalled) { 79a6b67f8cbb80323786f7e5d9db442f080e242d76Aurimas Liutikas // Pre-v16 seems to have a bug where onAnimationEnd is called 80a6b67f8cbb80323786f7e5d9db442f080e242d76Aurimas Liutikas // twice, therefore we only dispatch on the first call 81a6b67f8cbb80323786f7e5d9db442f080e242d76Aurimas Liutikas if (mVpa.mEndAction != null) { 82a6b67f8cbb80323786f7e5d9db442f080e242d76Aurimas Liutikas Runnable endAction = mVpa.mEndAction; 83a6b67f8cbb80323786f7e5d9db442f080e242d76Aurimas Liutikas mVpa.mEndAction = null; 84a6b67f8cbb80323786f7e5d9db442f080e242d76Aurimas Liutikas endAction.run(); 85ead7065c8e987fefca4d0d850d824fb7d7bce677Chet Haase } 86ead7065c8e987fefca4d0d850d824fb7d7bce677Chet Haase Object listenerTag = view.getTag(LISTENER_TAG_ID); 87ead7065c8e987fefca4d0d850d824fb7d7bce677Chet Haase ViewPropertyAnimatorListener listener = null; 88ead7065c8e987fefca4d0d850d824fb7d7bce677Chet Haase if (listenerTag instanceof ViewPropertyAnimatorListener) { 89ead7065c8e987fefca4d0d850d824fb7d7bce677Chet Haase listener = (ViewPropertyAnimatorListener) listenerTag; 90797c82a7055f7ba825169388465617f0db716739Chet Haase } 91797c82a7055f7ba825169388465617f0db716739Chet Haase if (listener != null) { 92a6b67f8cbb80323786f7e5d9db442f080e242d76Aurimas Liutikas listener.onAnimationEnd(view); 93797c82a7055f7ba825169388465617f0db716739Chet Haase } 94a6b67f8cbb80323786f7e5d9db442f080e242d76Aurimas Liutikas mAnimEndCalled = true; 95797c82a7055f7ba825169388465617f0db716739Chet Haase } 96d7d27e9ebe5c7325e67e1a8af265378bd2056cadChet Haase } 97d7d27e9ebe5c7325e67e1a8af265378bd2056cadChet Haase 98d7d27e9ebe5c7325e67e1a8af265378bd2056cadChet Haase @Override 99a6b67f8cbb80323786f7e5d9db442f080e242d76Aurimas Liutikas public void onAnimationCancel(View view) { 100a6b67f8cbb80323786f7e5d9db442f080e242d76Aurimas Liutikas Object listenerTag = view.getTag(LISTENER_TAG_ID); 101a6b67f8cbb80323786f7e5d9db442f080e242d76Aurimas Liutikas ViewPropertyAnimatorListener listener = null; 102a6b67f8cbb80323786f7e5d9db442f080e242d76Aurimas Liutikas if (listenerTag instanceof ViewPropertyAnimatorListener) { 103a6b67f8cbb80323786f7e5d9db442f080e242d76Aurimas Liutikas listener = (ViewPropertyAnimatorListener) listenerTag; 104a6b67f8cbb80323786f7e5d9db442f080e242d76Aurimas Liutikas } 105a6b67f8cbb80323786f7e5d9db442f080e242d76Aurimas Liutikas if (listener != null) { 106a6b67f8cbb80323786f7e5d9db442f080e242d76Aurimas Liutikas listener.onAnimationCancel(view); 107a6b67f8cbb80323786f7e5d9db442f080e242d76Aurimas Liutikas } 108d7d27e9ebe5c7325e67e1a8af265378bd2056cadChet Haase } 109d7d27e9ebe5c7325e67e1a8af265378bd2056cadChet Haase } 110d7d27e9ebe5c7325e67e1a8af265378bd2056cadChet Haase 111d7d27e9ebe5c7325e67e1a8af265378bd2056cadChet Haase /** 112d7d27e9ebe5c7325e67e1a8af265378bd2056cadChet Haase * Sets the duration for the underlying animator that animates the requested properties. 113d7d27e9ebe5c7325e67e1a8af265378bd2056cadChet Haase * By default, the animator uses the default value for ValueAnimator. Calling this method 114d7d27e9ebe5c7325e67e1a8af265378bd2056cadChet Haase * will cause the declared value to be used instead. 115d7d27e9ebe5c7325e67e1a8af265378bd2056cadChet Haase * 116d7d27e9ebe5c7325e67e1a8af265378bd2056cadChet Haase * @param value The length of ensuing property animations, in milliseconds. The value 117d7d27e9ebe5c7325e67e1a8af265378bd2056cadChet Haase * cannot be negative. 118d7d27e9ebe5c7325e67e1a8af265378bd2056cadChet Haase * @return This object, allowing calls to methods in this class to be chained. 119d7d27e9ebe5c7325e67e1a8af265378bd2056cadChet Haase */ 120d7d27e9ebe5c7325e67e1a8af265378bd2056cadChet Haase public ViewPropertyAnimatorCompat setDuration(long value) { 121d7d27e9ebe5c7325e67e1a8af265378bd2056cadChet Haase View view; 122d7d27e9ebe5c7325e67e1a8af265378bd2056cadChet Haase if ((view = mView.get()) != null) { 123846955fba824b96d8cca48e372353d5b7cc31955Aurimas Liutikas view.animate().setDuration(value); 124d7d27e9ebe5c7325e67e1a8af265378bd2056cadChet Haase } 125d7d27e9ebe5c7325e67e1a8af265378bd2056cadChet Haase return this; 126d7d27e9ebe5c7325e67e1a8af265378bd2056cadChet Haase } 127d7d27e9ebe5c7325e67e1a8af265378bd2056cadChet Haase 128d7d27e9ebe5c7325e67e1a8af265378bd2056cadChet Haase /** 129d7d27e9ebe5c7325e67e1a8af265378bd2056cadChet Haase * This method will cause the View's <code>alpha</code> property to be animated to the 130d7d27e9ebe5c7325e67e1a8af265378bd2056cadChet Haase * specified value. Animations already running on the property will be canceled. 131d7d27e9ebe5c7325e67e1a8af265378bd2056cadChet Haase * 132d7d27e9ebe5c7325e67e1a8af265378bd2056cadChet Haase * @param value The value to be animated to. 133d7d27e9ebe5c7325e67e1a8af265378bd2056cadChet Haase * @return This object, allowing calls to methods in this class to be chained. 134d7d27e9ebe5c7325e67e1a8af265378bd2056cadChet Haase */ 135d7d27e9ebe5c7325e67e1a8af265378bd2056cadChet Haase public ViewPropertyAnimatorCompat alpha(float value) { 136d7d27e9ebe5c7325e67e1a8af265378bd2056cadChet Haase View view; 137d7d27e9ebe5c7325e67e1a8af265378bd2056cadChet Haase if ((view = mView.get()) != null) { 138846955fba824b96d8cca48e372353d5b7cc31955Aurimas Liutikas view.animate().alpha(value); 139d7d27e9ebe5c7325e67e1a8af265378bd2056cadChet Haase } 140d7d27e9ebe5c7325e67e1a8af265378bd2056cadChet Haase return this; 141d7d27e9ebe5c7325e67e1a8af265378bd2056cadChet Haase } 142d7d27e9ebe5c7325e67e1a8af265378bd2056cadChet Haase 143d7d27e9ebe5c7325e67e1a8af265378bd2056cadChet Haase /** 144d7d27e9ebe5c7325e67e1a8af265378bd2056cadChet Haase * This method will cause the View's <code>alpha</code> property to be animated by the 145d7d27e9ebe5c7325e67e1a8af265378bd2056cadChet Haase * specified value. Animations already running on the property will be canceled. 146d7d27e9ebe5c7325e67e1a8af265378bd2056cadChet Haase * 147d7d27e9ebe5c7325e67e1a8af265378bd2056cadChet Haase * @param value The amount to be animated by, as an offset from the current value. 148d7d27e9ebe5c7325e67e1a8af265378bd2056cadChet Haase * @return This object, allowing calls to methods in this class to be chained. 149d7d27e9ebe5c7325e67e1a8af265378bd2056cadChet Haase */ 150d7d27e9ebe5c7325e67e1a8af265378bd2056cadChet Haase public ViewPropertyAnimatorCompat alphaBy(float value) { 151d7d27e9ebe5c7325e67e1a8af265378bd2056cadChet Haase View view; 152d7d27e9ebe5c7325e67e1a8af265378bd2056cadChet Haase if ((view = mView.get()) != null) { 153846955fba824b96d8cca48e372353d5b7cc31955Aurimas Liutikas view.animate().alphaBy(value); 154d7d27e9ebe5c7325e67e1a8af265378bd2056cadChet Haase } 155d7d27e9ebe5c7325e67e1a8af265378bd2056cadChet Haase return this; 156d7d27e9ebe5c7325e67e1a8af265378bd2056cadChet Haase } 157d7d27e9ebe5c7325e67e1a8af265378bd2056cadChet Haase 158d7d27e9ebe5c7325e67e1a8af265378bd2056cadChet Haase /** 159d7d27e9ebe5c7325e67e1a8af265378bd2056cadChet Haase * This method will cause the View's <code>translationX</code> property to be animated to the 160d7d27e9ebe5c7325e67e1a8af265378bd2056cadChet Haase * specified value. Animations already running on the property will be canceled. 161d7d27e9ebe5c7325e67e1a8af265378bd2056cadChet Haase * 162d7d27e9ebe5c7325e67e1a8af265378bd2056cadChet Haase * @param value The value to be animated to. 163d7d27e9ebe5c7325e67e1a8af265378bd2056cadChet Haase * @return This object, allowing calls to methods in this class to be chained. 164d7d27e9ebe5c7325e67e1a8af265378bd2056cadChet Haase */ 165d7d27e9ebe5c7325e67e1a8af265378bd2056cadChet Haase public ViewPropertyAnimatorCompat translationX(float value) { 166d7d27e9ebe5c7325e67e1a8af265378bd2056cadChet Haase View view; 167d7d27e9ebe5c7325e67e1a8af265378bd2056cadChet Haase if ((view = mView.get()) != null) { 168846955fba824b96d8cca48e372353d5b7cc31955Aurimas Liutikas view.animate().translationX(value); 169d7d27e9ebe5c7325e67e1a8af265378bd2056cadChet Haase } 170d7d27e9ebe5c7325e67e1a8af265378bd2056cadChet Haase return this; 171d7d27e9ebe5c7325e67e1a8af265378bd2056cadChet Haase } 172d7d27e9ebe5c7325e67e1a8af265378bd2056cadChet Haase 173d7d27e9ebe5c7325e67e1a8af265378bd2056cadChet Haase /** 174d7d27e9ebe5c7325e67e1a8af265378bd2056cadChet Haase * This method will cause the View's <code>translationY</code> property to be animated to the 175d7d27e9ebe5c7325e67e1a8af265378bd2056cadChet Haase * specified value. Animations already running on the property will be canceled. 176d7d27e9ebe5c7325e67e1a8af265378bd2056cadChet Haase * 177d7d27e9ebe5c7325e67e1a8af265378bd2056cadChet Haase * @param value The value to be animated to. 178d7d27e9ebe5c7325e67e1a8af265378bd2056cadChet Haase * @return This object, allowing calls to methods in this class to be chained. 179d7d27e9ebe5c7325e67e1a8af265378bd2056cadChet Haase */ 180d7d27e9ebe5c7325e67e1a8af265378bd2056cadChet Haase public ViewPropertyAnimatorCompat translationY(float value) { 181d7d27e9ebe5c7325e67e1a8af265378bd2056cadChet Haase View view; 182d7d27e9ebe5c7325e67e1a8af265378bd2056cadChet Haase if ((view = mView.get()) != null) { 183846955fba824b96d8cca48e372353d5b7cc31955Aurimas Liutikas view.animate().translationY(value); 184d7d27e9ebe5c7325e67e1a8af265378bd2056cadChet Haase } 185d7d27e9ebe5c7325e67e1a8af265378bd2056cadChet Haase return this; 186d7d27e9ebe5c7325e67e1a8af265378bd2056cadChet Haase } 187d7d27e9ebe5c7325e67e1a8af265378bd2056cadChet Haase 188d7d27e9ebe5c7325e67e1a8af265378bd2056cadChet Haase /** 189d7d27e9ebe5c7325e67e1a8af265378bd2056cadChet Haase * Specifies an action to take place when the next animation ends. The action is only 190d7d27e9ebe5c7325e67e1a8af265378bd2056cadChet Haase * run if the animation ends normally; if the ViewPropertyAnimator is canceled during 191d7d27e9ebe5c7325e67e1a8af265378bd2056cadChet Haase * that animation, the runnable will not run. 192d7d27e9ebe5c7325e67e1a8af265378bd2056cadChet Haase * This method, along with {@link #withStartAction(Runnable)}, is intended to help facilitate 193d7d27e9ebe5c7325e67e1a8af265378bd2056cadChet Haase * choreographing ViewPropertyAnimator animations with other animations or actions 194d7d27e9ebe5c7325e67e1a8af265378bd2056cadChet Haase * in the application. 195d7d27e9ebe5c7325e67e1a8af265378bd2056cadChet Haase * 196d7d27e9ebe5c7325e67e1a8af265378bd2056cadChet Haase * <p>For example, the following code animates a view to x=200 and then back to 0:</p> 197d7d27e9ebe5c7325e67e1a8af265378bd2056cadChet Haase * <pre> 198d7d27e9ebe5c7325e67e1a8af265378bd2056cadChet Haase * Runnable endAction = new Runnable() { 199d7d27e9ebe5c7325e67e1a8af265378bd2056cadChet Haase * public void run() { 200d7d27e9ebe5c7325e67e1a8af265378bd2056cadChet Haase * view.animate().x(0); 201d7d27e9ebe5c7325e67e1a8af265378bd2056cadChet Haase * } 202d7d27e9ebe5c7325e67e1a8af265378bd2056cadChet Haase * }; 203d7d27e9ebe5c7325e67e1a8af265378bd2056cadChet Haase * view.animate().x(200).withEndAction(endAction); 204d7d27e9ebe5c7325e67e1a8af265378bd2056cadChet Haase * </pre> 205d7d27e9ebe5c7325e67e1a8af265378bd2056cadChet Haase * 206d7d27e9ebe5c7325e67e1a8af265378bd2056cadChet Haase * <p>For API 14 and 15, this method will run by setting 207d7d27e9ebe5c7325e67e1a8af265378bd2056cadChet Haase * a listener on the ViewPropertyAnimatorCompat object and running the action 208d7d27e9ebe5c7325e67e1a8af265378bd2056cadChet Haase * in that listener's {@link ViewPropertyAnimatorListener#onAnimationEnd(View)} method.</p> 209d7d27e9ebe5c7325e67e1a8af265378bd2056cadChet Haase * 210d7d27e9ebe5c7325e67e1a8af265378bd2056cadChet Haase * @param runnable The action to run when the next animation ends. 211d7d27e9ebe5c7325e67e1a8af265378bd2056cadChet Haase * @return This object, allowing calls to methods in this class to be chained. 212d7d27e9ebe5c7325e67e1a8af265378bd2056cadChet Haase */ 213d7d27e9ebe5c7325e67e1a8af265378bd2056cadChet Haase public ViewPropertyAnimatorCompat withEndAction(Runnable runnable) { 214d7d27e9ebe5c7325e67e1a8af265378bd2056cadChet Haase View view; 215d7d27e9ebe5c7325e67e1a8af265378bd2056cadChet Haase if ((view = mView.get()) != null) { 216a6b67f8cbb80323786f7e5d9db442f080e242d76Aurimas Liutikas if (Build.VERSION.SDK_INT >= 16) { 217a6b67f8cbb80323786f7e5d9db442f080e242d76Aurimas Liutikas view.animate().withEndAction(runnable); 218a6b67f8cbb80323786f7e5d9db442f080e242d76Aurimas Liutikas } else { 219a6b67f8cbb80323786f7e5d9db442f080e242d76Aurimas Liutikas setListenerInternal(view, new ViewPropertyAnimatorListenerApi14(this)); 220a6b67f8cbb80323786f7e5d9db442f080e242d76Aurimas Liutikas mEndAction = runnable; 221a6b67f8cbb80323786f7e5d9db442f080e242d76Aurimas Liutikas } 222d7d27e9ebe5c7325e67e1a8af265378bd2056cadChet Haase } 223d7d27e9ebe5c7325e67e1a8af265378bd2056cadChet Haase return this; 224d7d27e9ebe5c7325e67e1a8af265378bd2056cadChet Haase } 225d7d27e9ebe5c7325e67e1a8af265378bd2056cadChet Haase 226d7d27e9ebe5c7325e67e1a8af265378bd2056cadChet Haase /** 227d7d27e9ebe5c7325e67e1a8af265378bd2056cadChet Haase * Returns the current duration of property animations. If the duration was set on this 228d7d27e9ebe5c7325e67e1a8af265378bd2056cadChet Haase * object, that value is returned. Otherwise, the default value of the underlying Animator 229d7d27e9ebe5c7325e67e1a8af265378bd2056cadChet Haase * is returned. 230d7d27e9ebe5c7325e67e1a8af265378bd2056cadChet Haase * 231d7d27e9ebe5c7325e67e1a8af265378bd2056cadChet Haase * @see #setDuration(long) 232d7d27e9ebe5c7325e67e1a8af265378bd2056cadChet Haase * @return The duration of animations, in milliseconds. 233d7d27e9ebe5c7325e67e1a8af265378bd2056cadChet Haase */ 234d7d27e9ebe5c7325e67e1a8af265378bd2056cadChet Haase public long getDuration() { 235d7d27e9ebe5c7325e67e1a8af265378bd2056cadChet Haase View view; 236d7d27e9ebe5c7325e67e1a8af265378bd2056cadChet Haase if ((view = mView.get()) != null) { 237846955fba824b96d8cca48e372353d5b7cc31955Aurimas Liutikas return view.animate().getDuration(); 238d7d27e9ebe5c7325e67e1a8af265378bd2056cadChet Haase } else { 239d7d27e9ebe5c7325e67e1a8af265378bd2056cadChet Haase return 0; 240d7d27e9ebe5c7325e67e1a8af265378bd2056cadChet Haase } 241d7d27e9ebe5c7325e67e1a8af265378bd2056cadChet Haase } 242d7d27e9ebe5c7325e67e1a8af265378bd2056cadChet Haase 243d7d27e9ebe5c7325e67e1a8af265378bd2056cadChet Haase /** 244d7d27e9ebe5c7325e67e1a8af265378bd2056cadChet Haase * Sets the interpolator for the underlying animator that animates the requested properties. 245d7d27e9ebe5c7325e67e1a8af265378bd2056cadChet Haase * By default, the animator uses the default interpolator for ValueAnimator. Calling this method 246d7d27e9ebe5c7325e67e1a8af265378bd2056cadChet Haase * will cause the declared object to be used instead. 247d7d27e9ebe5c7325e67e1a8af265378bd2056cadChet Haase * 248d7d27e9ebe5c7325e67e1a8af265378bd2056cadChet Haase * @param value The TimeInterpolator to be used for ensuing property animations. 249d7d27e9ebe5c7325e67e1a8af265378bd2056cadChet Haase * @return This object, allowing calls to methods in this class to be chained. 250d7d27e9ebe5c7325e67e1a8af265378bd2056cadChet Haase */ 251d7d27e9ebe5c7325e67e1a8af265378bd2056cadChet Haase public ViewPropertyAnimatorCompat setInterpolator(Interpolator value) { 252d7d27e9ebe5c7325e67e1a8af265378bd2056cadChet Haase View view; 253d7d27e9ebe5c7325e67e1a8af265378bd2056cadChet Haase if ((view = mView.get()) != null) { 254846955fba824b96d8cca48e372353d5b7cc31955Aurimas Liutikas view.animate().setInterpolator(value); 255d7d27e9ebe5c7325e67e1a8af265378bd2056cadChet Haase } 256d7d27e9ebe5c7325e67e1a8af265378bd2056cadChet Haase return this; 257d7d27e9ebe5c7325e67e1a8af265378bd2056cadChet Haase } 258d7d27e9ebe5c7325e67e1a8af265378bd2056cadChet Haase 259d7d27e9ebe5c7325e67e1a8af265378bd2056cadChet Haase /** 260d7d27e9ebe5c7325e67e1a8af265378bd2056cadChet Haase * Returns the timing interpolator that this animation uses. 261d7d27e9ebe5c7325e67e1a8af265378bd2056cadChet Haase * 262d7d27e9ebe5c7325e67e1a8af265378bd2056cadChet Haase * @return The timing interpolator for this animation. 263d7d27e9ebe5c7325e67e1a8af265378bd2056cadChet Haase */ 264d7d27e9ebe5c7325e67e1a8af265378bd2056cadChet Haase public Interpolator getInterpolator() { 265d7d27e9ebe5c7325e67e1a8af265378bd2056cadChet Haase View view; 266d7d27e9ebe5c7325e67e1a8af265378bd2056cadChet Haase if ((view = mView.get()) != null) { 267a6b67f8cbb80323786f7e5d9db442f080e242d76Aurimas Liutikas if (Build.VERSION.SDK_INT >= 18) { 268a6b67f8cbb80323786f7e5d9db442f080e242d76Aurimas Liutikas return (Interpolator) view.animate().getInterpolator(); 269a6b67f8cbb80323786f7e5d9db442f080e242d76Aurimas Liutikas } 270d7d27e9ebe5c7325e67e1a8af265378bd2056cadChet Haase } 271a6b67f8cbb80323786f7e5d9db442f080e242d76Aurimas Liutikas return null; 272d7d27e9ebe5c7325e67e1a8af265378bd2056cadChet Haase } 273d7d27e9ebe5c7325e67e1a8af265378bd2056cadChet Haase 274d7d27e9ebe5c7325e67e1a8af265378bd2056cadChet Haase /** 275d7d27e9ebe5c7325e67e1a8af265378bd2056cadChet Haase * Sets the startDelay for the underlying animator that animates the requested properties. 276d7d27e9ebe5c7325e67e1a8af265378bd2056cadChet Haase * By default, the animator uses the default value for ValueAnimator. Calling this method 277d7d27e9ebe5c7325e67e1a8af265378bd2056cadChet Haase * will cause the declared value to be used instead. 278d7d27e9ebe5c7325e67e1a8af265378bd2056cadChet Haase * 279d7d27e9ebe5c7325e67e1a8af265378bd2056cadChet Haase * @param value The delay of ensuing property animations, in milliseconds. The value 280d7d27e9ebe5c7325e67e1a8af265378bd2056cadChet Haase * cannot be negative. 281d7d27e9ebe5c7325e67e1a8af265378bd2056cadChet Haase * @return This object, allowing calls to methods in this class to be chained. 282d7d27e9ebe5c7325e67e1a8af265378bd2056cadChet Haase */ 283d7d27e9ebe5c7325e67e1a8af265378bd2056cadChet Haase public ViewPropertyAnimatorCompat setStartDelay(long value) { 284d7d27e9ebe5c7325e67e1a8af265378bd2056cadChet Haase View view; 285d7d27e9ebe5c7325e67e1a8af265378bd2056cadChet Haase if ((view = mView.get()) != null) { 286846955fba824b96d8cca48e372353d5b7cc31955Aurimas Liutikas view.animate().setStartDelay(value); 287d7d27e9ebe5c7325e67e1a8af265378bd2056cadChet Haase } 288d7d27e9ebe5c7325e67e1a8af265378bd2056cadChet Haase return this; 289d7d27e9ebe5c7325e67e1a8af265378bd2056cadChet Haase } 290d7d27e9ebe5c7325e67e1a8af265378bd2056cadChet Haase 291d7d27e9ebe5c7325e67e1a8af265378bd2056cadChet Haase /** 292d7d27e9ebe5c7325e67e1a8af265378bd2056cadChet Haase * Returns the current startDelay of property animations. If the startDelay was set on this 293d7d27e9ebe5c7325e67e1a8af265378bd2056cadChet Haase * object, that value is returned. Otherwise, the default value of the underlying Animator 294d7d27e9ebe5c7325e67e1a8af265378bd2056cadChet Haase * is returned. 295d7d27e9ebe5c7325e67e1a8af265378bd2056cadChet Haase * 296d7d27e9ebe5c7325e67e1a8af265378bd2056cadChet Haase * @see #setStartDelay(long) 297d7d27e9ebe5c7325e67e1a8af265378bd2056cadChet Haase * @return The startDelay of animations, in milliseconds. 298d7d27e9ebe5c7325e67e1a8af265378bd2056cadChet Haase */ 299d7d27e9ebe5c7325e67e1a8af265378bd2056cadChet Haase public long getStartDelay() { 300d7d27e9ebe5c7325e67e1a8af265378bd2056cadChet Haase View view; 301d7d27e9ebe5c7325e67e1a8af265378bd2056cadChet Haase if ((view = mView.get()) != null) { 302846955fba824b96d8cca48e372353d5b7cc31955Aurimas Liutikas return view.animate().getStartDelay(); 303d7d27e9ebe5c7325e67e1a8af265378bd2056cadChet Haase } else { 304d7d27e9ebe5c7325e67e1a8af265378bd2056cadChet Haase return 0; 305d7d27e9ebe5c7325e67e1a8af265378bd2056cadChet Haase } 306d7d27e9ebe5c7325e67e1a8af265378bd2056cadChet Haase } 307d7d27e9ebe5c7325e67e1a8af265378bd2056cadChet Haase 308d7d27e9ebe5c7325e67e1a8af265378bd2056cadChet Haase /** 309d7d27e9ebe5c7325e67e1a8af265378bd2056cadChet Haase * This method will cause the View's <code>rotation</code> property to be animated to the 310d7d27e9ebe5c7325e67e1a8af265378bd2056cadChet Haase * specified value. Animations already running on the property will be canceled. 311d7d27e9ebe5c7325e67e1a8af265378bd2056cadChet Haase * 312d7d27e9ebe5c7325e67e1a8af265378bd2056cadChet Haase * @param value The value to be animated to. 313d7d27e9ebe5c7325e67e1a8af265378bd2056cadChet Haase * @return This object, allowing calls to methods in this class to be chained. 314d7d27e9ebe5c7325e67e1a8af265378bd2056cadChet Haase */ 315d7d27e9ebe5c7325e67e1a8af265378bd2056cadChet Haase public ViewPropertyAnimatorCompat rotation(float value) { 316d7d27e9ebe5c7325e67e1a8af265378bd2056cadChet Haase View view; 317d7d27e9ebe5c7325e67e1a8af265378bd2056cadChet Haase if ((view = mView.get()) != null) { 318846955fba824b96d8cca48e372353d5b7cc31955Aurimas Liutikas view.animate().rotation(value); 319d7d27e9ebe5c7325e67e1a8af265378bd2056cadChet Haase } 320d7d27e9ebe5c7325e67e1a8af265378bd2056cadChet Haase return this; 321d7d27e9ebe5c7325e67e1a8af265378bd2056cadChet Haase } 322d7d27e9ebe5c7325e67e1a8af265378bd2056cadChet Haase 323d7d27e9ebe5c7325e67e1a8af265378bd2056cadChet Haase /** 324d7d27e9ebe5c7325e67e1a8af265378bd2056cadChet Haase * This method will cause the View's <code>rotation</code> property to be animated by the 325d7d27e9ebe5c7325e67e1a8af265378bd2056cadChet Haase * specified value. Animations already running on the property will be canceled. 326d7d27e9ebe5c7325e67e1a8af265378bd2056cadChet Haase * 327d7d27e9ebe5c7325e67e1a8af265378bd2056cadChet Haase * @param value The amount to be animated by, as an offset from the current value. 328d7d27e9ebe5c7325e67e1a8af265378bd2056cadChet Haase * @return This object, allowing calls to methods in this class to be chained. 329d7d27e9ebe5c7325e67e1a8af265378bd2056cadChet Haase */ 330d7d27e9ebe5c7325e67e1a8af265378bd2056cadChet Haase public ViewPropertyAnimatorCompat rotationBy(float value) { 331d7d27e9ebe5c7325e67e1a8af265378bd2056cadChet Haase View view; 332d7d27e9ebe5c7325e67e1a8af265378bd2056cadChet Haase if ((view = mView.get()) != null) { 333846955fba824b96d8cca48e372353d5b7cc31955Aurimas Liutikas view.animate().rotationBy(value); 334d7d27e9ebe5c7325e67e1a8af265378bd2056cadChet Haase } 335d7d27e9ebe5c7325e67e1a8af265378bd2056cadChet Haase return this; 336d7d27e9ebe5c7325e67e1a8af265378bd2056cadChet Haase } 337d7d27e9ebe5c7325e67e1a8af265378bd2056cadChet Haase 338d7d27e9ebe5c7325e67e1a8af265378bd2056cadChet Haase /** 339d7d27e9ebe5c7325e67e1a8af265378bd2056cadChet Haase * This method will cause the View's <code>rotationX</code> property to be animated to the 340d7d27e9ebe5c7325e67e1a8af265378bd2056cadChet Haase * specified value. Animations already running on the property will be canceled. 341d7d27e9ebe5c7325e67e1a8af265378bd2056cadChet Haase * 342d7d27e9ebe5c7325e67e1a8af265378bd2056cadChet Haase * @param value The value to be animated to. 343d7d27e9ebe5c7325e67e1a8af265378bd2056cadChet Haase * @return This object, allowing calls to methods in this class to be chained. 344d7d27e9ebe5c7325e67e1a8af265378bd2056cadChet Haase */ 345d7d27e9ebe5c7325e67e1a8af265378bd2056cadChet Haase public ViewPropertyAnimatorCompat rotationX(float value) { 346d7d27e9ebe5c7325e67e1a8af265378bd2056cadChet Haase View view; 347d7d27e9ebe5c7325e67e1a8af265378bd2056cadChet Haase if ((view = mView.get()) != null) { 348846955fba824b96d8cca48e372353d5b7cc31955Aurimas Liutikas view.animate().rotationX(value); 349d7d27e9ebe5c7325e67e1a8af265378bd2056cadChet Haase } 350d7d27e9ebe5c7325e67e1a8af265378bd2056cadChet Haase return this; 351d7d27e9ebe5c7325e67e1a8af265378bd2056cadChet Haase } 352d7d27e9ebe5c7325e67e1a8af265378bd2056cadChet Haase 353d7d27e9ebe5c7325e67e1a8af265378bd2056cadChet Haase /** 354d7d27e9ebe5c7325e67e1a8af265378bd2056cadChet Haase * This method will cause the View's <code>rotationX</code> property to be animated by the 355d7d27e9ebe5c7325e67e1a8af265378bd2056cadChet Haase * specified value. Animations already running on the property will be canceled. 356d7d27e9ebe5c7325e67e1a8af265378bd2056cadChet Haase * 357d7d27e9ebe5c7325e67e1a8af265378bd2056cadChet Haase * @param value The amount to be animated by, as an offset from the current value. 358d7d27e9ebe5c7325e67e1a8af265378bd2056cadChet Haase * @return This object, allowing calls to methods in this class to be chained. 359d7d27e9ebe5c7325e67e1a8af265378bd2056cadChet Haase */ 360d7d27e9ebe5c7325e67e1a8af265378bd2056cadChet Haase public ViewPropertyAnimatorCompat rotationXBy(float value) { 361d7d27e9ebe5c7325e67e1a8af265378bd2056cadChet Haase View view; 362d7d27e9ebe5c7325e67e1a8af265378bd2056cadChet Haase if ((view = mView.get()) != null) { 363846955fba824b96d8cca48e372353d5b7cc31955Aurimas Liutikas view.animate().rotationXBy(value); 364d7d27e9ebe5c7325e67e1a8af265378bd2056cadChet Haase } 365d7d27e9ebe5c7325e67e1a8af265378bd2056cadChet Haase return this; 366d7d27e9ebe5c7325e67e1a8af265378bd2056cadChet Haase } 367d7d27e9ebe5c7325e67e1a8af265378bd2056cadChet Haase 368d7d27e9ebe5c7325e67e1a8af265378bd2056cadChet Haase /** 369d7d27e9ebe5c7325e67e1a8af265378bd2056cadChet Haase * This method will cause the View's <code>rotationY</code> property to be animated to the 370d7d27e9ebe5c7325e67e1a8af265378bd2056cadChet Haase * specified value. Animations already running on the property will be canceled. 371d7d27e9ebe5c7325e67e1a8af265378bd2056cadChet Haase * 372d7d27e9ebe5c7325e67e1a8af265378bd2056cadChet Haase * @param value The value to be animated to. 373d7d27e9ebe5c7325e67e1a8af265378bd2056cadChet Haase * @return This object, allowing calls to methods in this class to be chained. 374d7d27e9ebe5c7325e67e1a8af265378bd2056cadChet Haase */ 375d7d27e9ebe5c7325e67e1a8af265378bd2056cadChet Haase public ViewPropertyAnimatorCompat rotationY(float value) { 376d7d27e9ebe5c7325e67e1a8af265378bd2056cadChet Haase View view; 377d7d27e9ebe5c7325e67e1a8af265378bd2056cadChet Haase if ((view = mView.get()) != null) { 378846955fba824b96d8cca48e372353d5b7cc31955Aurimas Liutikas view.animate().rotationY(value); 379d7d27e9ebe5c7325e67e1a8af265378bd2056cadChet Haase } 380d7d27e9ebe5c7325e67e1a8af265378bd2056cadChet Haase return this; 381d7d27e9ebe5c7325e67e1a8af265378bd2056cadChet Haase } 382d7d27e9ebe5c7325e67e1a8af265378bd2056cadChet Haase 383d7d27e9ebe5c7325e67e1a8af265378bd2056cadChet Haase /** 384d7d27e9ebe5c7325e67e1a8af265378bd2056cadChet Haase * This method will cause the View's <code>rotationY</code> property to be animated by the 385d7d27e9ebe5c7325e67e1a8af265378bd2056cadChet Haase * specified value. Animations already running on the property will be canceled. 386d7d27e9ebe5c7325e67e1a8af265378bd2056cadChet Haase * 387d7d27e9ebe5c7325e67e1a8af265378bd2056cadChet Haase * @param value The amount to be animated by, as an offset from the current value. 388d7d27e9ebe5c7325e67e1a8af265378bd2056cadChet Haase * @return This object, allowing calls to methods in this class to be chained. 389d7d27e9ebe5c7325e67e1a8af265378bd2056cadChet Haase */ 390d7d27e9ebe5c7325e67e1a8af265378bd2056cadChet Haase public ViewPropertyAnimatorCompat rotationYBy(float value) { 391d7d27e9ebe5c7325e67e1a8af265378bd2056cadChet Haase View view; 392d7d27e9ebe5c7325e67e1a8af265378bd2056cadChet Haase if ((view = mView.get()) != null) { 393846955fba824b96d8cca48e372353d5b7cc31955Aurimas Liutikas view.animate().rotationYBy(value); 394d7d27e9ebe5c7325e67e1a8af265378bd2056cadChet Haase } 395d7d27e9ebe5c7325e67e1a8af265378bd2056cadChet Haase return this; 396d7d27e9ebe5c7325e67e1a8af265378bd2056cadChet Haase } 397d7d27e9ebe5c7325e67e1a8af265378bd2056cadChet Haase 398d7d27e9ebe5c7325e67e1a8af265378bd2056cadChet Haase /** 399d7d27e9ebe5c7325e67e1a8af265378bd2056cadChet Haase * This method will cause the View's <code>scaleX</code> property to be animated to the 400d7d27e9ebe5c7325e67e1a8af265378bd2056cadChet Haase * specified value. Animations already running on the property will be canceled. 401d7d27e9ebe5c7325e67e1a8af265378bd2056cadChet Haase * 402d7d27e9ebe5c7325e67e1a8af265378bd2056cadChet Haase * @param value The value to be animated to. 403d7d27e9ebe5c7325e67e1a8af265378bd2056cadChet Haase * @return This object, allowing calls to methods in this class to be chained. 404d7d27e9ebe5c7325e67e1a8af265378bd2056cadChet Haase */ 405d7d27e9ebe5c7325e67e1a8af265378bd2056cadChet Haase public ViewPropertyAnimatorCompat scaleX(float value) { 406d7d27e9ebe5c7325e67e1a8af265378bd2056cadChet Haase View view; 407d7d27e9ebe5c7325e67e1a8af265378bd2056cadChet Haase if ((view = mView.get()) != null) { 408846955fba824b96d8cca48e372353d5b7cc31955Aurimas Liutikas view.animate().scaleX(value); 409d7d27e9ebe5c7325e67e1a8af265378bd2056cadChet Haase } 410d7d27e9ebe5c7325e67e1a8af265378bd2056cadChet Haase return this; 411d7d27e9ebe5c7325e67e1a8af265378bd2056cadChet Haase } 412d7d27e9ebe5c7325e67e1a8af265378bd2056cadChet Haase 413d7d27e9ebe5c7325e67e1a8af265378bd2056cadChet Haase /** 414d7d27e9ebe5c7325e67e1a8af265378bd2056cadChet Haase * This method will cause the View's <code>scaleX</code> property to be animated by the 415d7d27e9ebe5c7325e67e1a8af265378bd2056cadChet Haase * specified value. Animations already running on the property will be canceled. 416d7d27e9ebe5c7325e67e1a8af265378bd2056cadChet Haase * 417d7d27e9ebe5c7325e67e1a8af265378bd2056cadChet Haase * @param value The amount to be animated by, as an offset from the current value. 418d7d27e9ebe5c7325e67e1a8af265378bd2056cadChet Haase * @return This object, allowing calls to methods in this class to be chained. 419d7d27e9ebe5c7325e67e1a8af265378bd2056cadChet Haase */ 420d7d27e9ebe5c7325e67e1a8af265378bd2056cadChet Haase public ViewPropertyAnimatorCompat scaleXBy(float value) { 421d7d27e9ebe5c7325e67e1a8af265378bd2056cadChet Haase View view; 422d7d27e9ebe5c7325e67e1a8af265378bd2056cadChet Haase if ((view = mView.get()) != null) { 423846955fba824b96d8cca48e372353d5b7cc31955Aurimas Liutikas view.animate().scaleXBy(value); 424d7d27e9ebe5c7325e67e1a8af265378bd2056cadChet Haase } 425d7d27e9ebe5c7325e67e1a8af265378bd2056cadChet Haase return this; 426d7d27e9ebe5c7325e67e1a8af265378bd2056cadChet Haase } 427d7d27e9ebe5c7325e67e1a8af265378bd2056cadChet Haase 428d7d27e9ebe5c7325e67e1a8af265378bd2056cadChet Haase /** 429d7d27e9ebe5c7325e67e1a8af265378bd2056cadChet Haase * This method will cause the View's <code>scaleY</code> property to be animated to the 430d7d27e9ebe5c7325e67e1a8af265378bd2056cadChet Haase * specified value. Animations already running on the property will be canceled. 431d7d27e9ebe5c7325e67e1a8af265378bd2056cadChet Haase * 432d7d27e9ebe5c7325e67e1a8af265378bd2056cadChet Haase * @param value The value to be animated to. 433d7d27e9ebe5c7325e67e1a8af265378bd2056cadChet Haase * @return This object, allowing calls to methods in this class to be chained. 434d7d27e9ebe5c7325e67e1a8af265378bd2056cadChet Haase */ 435d7d27e9ebe5c7325e67e1a8af265378bd2056cadChet Haase public ViewPropertyAnimatorCompat scaleY(float value) { 436d7d27e9ebe5c7325e67e1a8af265378bd2056cadChet Haase View view; 437d7d27e9ebe5c7325e67e1a8af265378bd2056cadChet Haase if ((view = mView.get()) != null) { 438846955fba824b96d8cca48e372353d5b7cc31955Aurimas Liutikas view.animate().scaleY(value); 439d7d27e9ebe5c7325e67e1a8af265378bd2056cadChet Haase } 440d7d27e9ebe5c7325e67e1a8af265378bd2056cadChet Haase return this; 441d7d27e9ebe5c7325e67e1a8af265378bd2056cadChet Haase } 442d7d27e9ebe5c7325e67e1a8af265378bd2056cadChet Haase 443d7d27e9ebe5c7325e67e1a8af265378bd2056cadChet Haase /** 444d7d27e9ebe5c7325e67e1a8af265378bd2056cadChet Haase * This method will cause the View's <code>scaleY</code> property to be animated by the 445d7d27e9ebe5c7325e67e1a8af265378bd2056cadChet Haase * specified value. Animations already running on the property will be canceled. 446d7d27e9ebe5c7325e67e1a8af265378bd2056cadChet Haase * 447d7d27e9ebe5c7325e67e1a8af265378bd2056cadChet Haase * @param value The amount to be animated by, as an offset from the current value. 448d7d27e9ebe5c7325e67e1a8af265378bd2056cadChet Haase * @return This object, allowing calls to methods in this class to be chained. 449d7d27e9ebe5c7325e67e1a8af265378bd2056cadChet Haase */ 450d7d27e9ebe5c7325e67e1a8af265378bd2056cadChet Haase public ViewPropertyAnimatorCompat scaleYBy(float value) { 451d7d27e9ebe5c7325e67e1a8af265378bd2056cadChet Haase View view; 452d7d27e9ebe5c7325e67e1a8af265378bd2056cadChet Haase if ((view = mView.get()) != null) { 453846955fba824b96d8cca48e372353d5b7cc31955Aurimas Liutikas view.animate().scaleYBy(value); 454d7d27e9ebe5c7325e67e1a8af265378bd2056cadChet Haase } 455d7d27e9ebe5c7325e67e1a8af265378bd2056cadChet Haase return this; 456d7d27e9ebe5c7325e67e1a8af265378bd2056cadChet Haase } 457d7d27e9ebe5c7325e67e1a8af265378bd2056cadChet Haase 458d7d27e9ebe5c7325e67e1a8af265378bd2056cadChet Haase /** 459d7d27e9ebe5c7325e67e1a8af265378bd2056cadChet Haase * Cancels all property animations that are currently running or pending. 460d7d27e9ebe5c7325e67e1a8af265378bd2056cadChet Haase */ 461d7d27e9ebe5c7325e67e1a8af265378bd2056cadChet Haase public void cancel() { 462d7d27e9ebe5c7325e67e1a8af265378bd2056cadChet Haase View view; 463d7d27e9ebe5c7325e67e1a8af265378bd2056cadChet Haase if ((view = mView.get()) != null) { 464846955fba824b96d8cca48e372353d5b7cc31955Aurimas Liutikas view.animate().cancel(); 465d7d27e9ebe5c7325e67e1a8af265378bd2056cadChet Haase } 466d7d27e9ebe5c7325e67e1a8af265378bd2056cadChet Haase } 467d7d27e9ebe5c7325e67e1a8af265378bd2056cadChet Haase 468d7d27e9ebe5c7325e67e1a8af265378bd2056cadChet Haase /** 469d7d27e9ebe5c7325e67e1a8af265378bd2056cadChet Haase * This method will cause the View's <code>x</code> property to be animated to the 470d7d27e9ebe5c7325e67e1a8af265378bd2056cadChet Haase * specified value. Animations already running on the property will be canceled. 471d7d27e9ebe5c7325e67e1a8af265378bd2056cadChet Haase * 472d7d27e9ebe5c7325e67e1a8af265378bd2056cadChet Haase * @param value The value to be animated to. 473d7d27e9ebe5c7325e67e1a8af265378bd2056cadChet Haase * @return This object, allowing calls to methods in this class to be chained. 474d7d27e9ebe5c7325e67e1a8af265378bd2056cadChet Haase */ 475d7d27e9ebe5c7325e67e1a8af265378bd2056cadChet Haase public ViewPropertyAnimatorCompat x(float value) { 476d7d27e9ebe5c7325e67e1a8af265378bd2056cadChet Haase View view; 477d7d27e9ebe5c7325e67e1a8af265378bd2056cadChet Haase if ((view = mView.get()) != null) { 478846955fba824b96d8cca48e372353d5b7cc31955Aurimas Liutikas view.animate().x(value); 479d7d27e9ebe5c7325e67e1a8af265378bd2056cadChet Haase } 480d7d27e9ebe5c7325e67e1a8af265378bd2056cadChet Haase return this; 481d7d27e9ebe5c7325e67e1a8af265378bd2056cadChet Haase } 482d7d27e9ebe5c7325e67e1a8af265378bd2056cadChet Haase 483d7d27e9ebe5c7325e67e1a8af265378bd2056cadChet Haase /** 484d7d27e9ebe5c7325e67e1a8af265378bd2056cadChet Haase * This method will cause the View's <code>x</code> property to be animated by the 485d7d27e9ebe5c7325e67e1a8af265378bd2056cadChet Haase * specified value. Animations already running on the property will be canceled. 486d7d27e9ebe5c7325e67e1a8af265378bd2056cadChet Haase * 487d7d27e9ebe5c7325e67e1a8af265378bd2056cadChet Haase * @param value The amount to be animated by, as an offset from the current value. 488d7d27e9ebe5c7325e67e1a8af265378bd2056cadChet Haase * @return This object, allowing calls to methods in this class to be chained. 489d7d27e9ebe5c7325e67e1a8af265378bd2056cadChet Haase */ 490d7d27e9ebe5c7325e67e1a8af265378bd2056cadChet Haase public ViewPropertyAnimatorCompat xBy(float value) { 491d7d27e9ebe5c7325e67e1a8af265378bd2056cadChet Haase View view; 492d7d27e9ebe5c7325e67e1a8af265378bd2056cadChet Haase if ((view = mView.get()) != null) { 493846955fba824b96d8cca48e372353d5b7cc31955Aurimas Liutikas view.animate().xBy(value); 494d7d27e9ebe5c7325e67e1a8af265378bd2056cadChet Haase } 495d7d27e9ebe5c7325e67e1a8af265378bd2056cadChet Haase return this; 496d7d27e9ebe5c7325e67e1a8af265378bd2056cadChet Haase } 497d7d27e9ebe5c7325e67e1a8af265378bd2056cadChet Haase 498d7d27e9ebe5c7325e67e1a8af265378bd2056cadChet Haase /** 499d7d27e9ebe5c7325e67e1a8af265378bd2056cadChet Haase * This method will cause the View's <code>y</code> property to be animated to the 500d7d27e9ebe5c7325e67e1a8af265378bd2056cadChet Haase * specified value. Animations already running on the property will be canceled. 501d7d27e9ebe5c7325e67e1a8af265378bd2056cadChet Haase * 502d7d27e9ebe5c7325e67e1a8af265378bd2056cadChet Haase * @param value The value to be animated to. 503d7d27e9ebe5c7325e67e1a8af265378bd2056cadChet Haase * @return This object, allowing calls to methods in this class to be chained. 504d7d27e9ebe5c7325e67e1a8af265378bd2056cadChet Haase */ 505d7d27e9ebe5c7325e67e1a8af265378bd2056cadChet Haase public ViewPropertyAnimatorCompat y(float value) { 506d7d27e9ebe5c7325e67e1a8af265378bd2056cadChet Haase View view; 507d7d27e9ebe5c7325e67e1a8af265378bd2056cadChet Haase if ((view = mView.get()) != null) { 508846955fba824b96d8cca48e372353d5b7cc31955Aurimas Liutikas view.animate().y(value); 509d7d27e9ebe5c7325e67e1a8af265378bd2056cadChet Haase } 510d7d27e9ebe5c7325e67e1a8af265378bd2056cadChet Haase return this; 511d7d27e9ebe5c7325e67e1a8af265378bd2056cadChet Haase } 512d7d27e9ebe5c7325e67e1a8af265378bd2056cadChet Haase 513d7d27e9ebe5c7325e67e1a8af265378bd2056cadChet Haase /** 514d7d27e9ebe5c7325e67e1a8af265378bd2056cadChet Haase * This method will cause the View's <code>y</code> property to be animated by the 515d7d27e9ebe5c7325e67e1a8af265378bd2056cadChet Haase * specified value. Animations already running on the property will be canceled. 516d7d27e9ebe5c7325e67e1a8af265378bd2056cadChet Haase * 517d7d27e9ebe5c7325e67e1a8af265378bd2056cadChet Haase * @param value The amount to be animated by, as an offset from the current value. 518d7d27e9ebe5c7325e67e1a8af265378bd2056cadChet Haase * @return This object, allowing calls to methods in this class to be chained. 519d7d27e9ebe5c7325e67e1a8af265378bd2056cadChet Haase */ 520d7d27e9ebe5c7325e67e1a8af265378bd2056cadChet Haase public ViewPropertyAnimatorCompat yBy(float value) { 521d7d27e9ebe5c7325e67e1a8af265378bd2056cadChet Haase View view; 522d7d27e9ebe5c7325e67e1a8af265378bd2056cadChet Haase if ((view = mView.get()) != null) { 523846955fba824b96d8cca48e372353d5b7cc31955Aurimas Liutikas view.animate().yBy(value); 524d7d27e9ebe5c7325e67e1a8af265378bd2056cadChet Haase } 525d7d27e9ebe5c7325e67e1a8af265378bd2056cadChet Haase return this; 526d7d27e9ebe5c7325e67e1a8af265378bd2056cadChet Haase } 527d7d27e9ebe5c7325e67e1a8af265378bd2056cadChet Haase 528d7d27e9ebe5c7325e67e1a8af265378bd2056cadChet Haase /** 529d7d27e9ebe5c7325e67e1a8af265378bd2056cadChet Haase * This method will cause the View's <code>translationX</code> property to be animated by the 530d7d27e9ebe5c7325e67e1a8af265378bd2056cadChet Haase * specified value. Animations already running on the property will be canceled. 531d7d27e9ebe5c7325e67e1a8af265378bd2056cadChet Haase * 532d7d27e9ebe5c7325e67e1a8af265378bd2056cadChet Haase * @param value The amount to be animated by, as an offset from the current value. 533d7d27e9ebe5c7325e67e1a8af265378bd2056cadChet Haase * @return This object, allowing calls to methods in this class to be chained. 534d7d27e9ebe5c7325e67e1a8af265378bd2056cadChet Haase */ 535d7d27e9ebe5c7325e67e1a8af265378bd2056cadChet Haase public ViewPropertyAnimatorCompat translationXBy(float value) { 536d7d27e9ebe5c7325e67e1a8af265378bd2056cadChet Haase View view; 537d7d27e9ebe5c7325e67e1a8af265378bd2056cadChet Haase if ((view = mView.get()) != null) { 538846955fba824b96d8cca48e372353d5b7cc31955Aurimas Liutikas view.animate().translationXBy(value); 539d7d27e9ebe5c7325e67e1a8af265378bd2056cadChet Haase } 540d7d27e9ebe5c7325e67e1a8af265378bd2056cadChet Haase return this; 541d7d27e9ebe5c7325e67e1a8af265378bd2056cadChet Haase } 542d7d27e9ebe5c7325e67e1a8af265378bd2056cadChet Haase 543d7d27e9ebe5c7325e67e1a8af265378bd2056cadChet Haase /** 544d7d27e9ebe5c7325e67e1a8af265378bd2056cadChet Haase * This method will cause the View's <code>translationY</code> property to be animated by the 545d7d27e9ebe5c7325e67e1a8af265378bd2056cadChet Haase * specified value. Animations already running on the property will be canceled. 546d7d27e9ebe5c7325e67e1a8af265378bd2056cadChet Haase * 547d7d27e9ebe5c7325e67e1a8af265378bd2056cadChet Haase * @param value The amount to be animated by, as an offset from the current value. 548d7d27e9ebe5c7325e67e1a8af265378bd2056cadChet Haase * @return This object, allowing calls to methods in this class to be chained. 549d7d27e9ebe5c7325e67e1a8af265378bd2056cadChet Haase */ 550d7d27e9ebe5c7325e67e1a8af265378bd2056cadChet Haase public ViewPropertyAnimatorCompat translationYBy(float value) { 551d7d27e9ebe5c7325e67e1a8af265378bd2056cadChet Haase View view; 552d7d27e9ebe5c7325e67e1a8af265378bd2056cadChet Haase if ((view = mView.get()) != null) { 553846955fba824b96d8cca48e372353d5b7cc31955Aurimas Liutikas view.animate().translationYBy(value); 554d7d27e9ebe5c7325e67e1a8af265378bd2056cadChet Haase } 555d7d27e9ebe5c7325e67e1a8af265378bd2056cadChet Haase return this; 556d7d27e9ebe5c7325e67e1a8af265378bd2056cadChet Haase } 557d7d27e9ebe5c7325e67e1a8af265378bd2056cadChet Haase 558d7d27e9ebe5c7325e67e1a8af265378bd2056cadChet Haase /** 559e322b8bcc717dfd663677ed5cb59c6d1c3cb27afChris Banes * This method will cause the View's <code>translationZ</code> property to be animated by the 560e322b8bcc717dfd663677ed5cb59c6d1c3cb27afChris Banes * specified value. Animations already running on the property will be canceled. 561e322b8bcc717dfd663677ed5cb59c6d1c3cb27afChris Banes * 562e322b8bcc717dfd663677ed5cb59c6d1c3cb27afChris Banes * <p>Prior to API 21, this method will do nothing.</p> 563e322b8bcc717dfd663677ed5cb59c6d1c3cb27afChris Banes * 564e322b8bcc717dfd663677ed5cb59c6d1c3cb27afChris Banes * @param value The amount to be animated by, as an offset from the current value. 565e322b8bcc717dfd663677ed5cb59c6d1c3cb27afChris Banes * @return This object, allowing calls to methods in this class to be chained. 566e322b8bcc717dfd663677ed5cb59c6d1c3cb27afChris Banes */ 567e322b8bcc717dfd663677ed5cb59c6d1c3cb27afChris Banes public ViewPropertyAnimatorCompat translationZBy(float value) { 568e322b8bcc717dfd663677ed5cb59c6d1c3cb27afChris Banes View view; 569e322b8bcc717dfd663677ed5cb59c6d1c3cb27afChris Banes if ((view = mView.get()) != null) { 570a6b67f8cbb80323786f7e5d9db442f080e242d76Aurimas Liutikas if (Build.VERSION.SDK_INT >= 21) { 571a6b67f8cbb80323786f7e5d9db442f080e242d76Aurimas Liutikas view.animate().translationZBy(value); 572a6b67f8cbb80323786f7e5d9db442f080e242d76Aurimas Liutikas } 573e322b8bcc717dfd663677ed5cb59c6d1c3cb27afChris Banes } 574e322b8bcc717dfd663677ed5cb59c6d1c3cb27afChris Banes return this; 575e322b8bcc717dfd663677ed5cb59c6d1c3cb27afChris Banes } 576e322b8bcc717dfd663677ed5cb59c6d1c3cb27afChris Banes 577e322b8bcc717dfd663677ed5cb59c6d1c3cb27afChris Banes /** 578e322b8bcc717dfd663677ed5cb59c6d1c3cb27afChris Banes * This method will cause the View's <code>translationZ</code> property to be animated to the 579e322b8bcc717dfd663677ed5cb59c6d1c3cb27afChris Banes * specified value. Animations already running on the property will be canceled. 580e322b8bcc717dfd663677ed5cb59c6d1c3cb27afChris Banes * 581e322b8bcc717dfd663677ed5cb59c6d1c3cb27afChris Banes * <p>Prior to API 21, this method will do nothing.</p> 582e322b8bcc717dfd663677ed5cb59c6d1c3cb27afChris Banes * 583e322b8bcc717dfd663677ed5cb59c6d1c3cb27afChris Banes * @param value The amount to be animated by, as an offset from the current value. 584e322b8bcc717dfd663677ed5cb59c6d1c3cb27afChris Banes * @return This object, allowing calls to methods in this class to be chained. 585e322b8bcc717dfd663677ed5cb59c6d1c3cb27afChris Banes */ 586e322b8bcc717dfd663677ed5cb59c6d1c3cb27afChris Banes public ViewPropertyAnimatorCompat translationZ(float value) { 587e322b8bcc717dfd663677ed5cb59c6d1c3cb27afChris Banes View view; 588e322b8bcc717dfd663677ed5cb59c6d1c3cb27afChris Banes if ((view = mView.get()) != null) { 589a6b67f8cbb80323786f7e5d9db442f080e242d76Aurimas Liutikas if (Build.VERSION.SDK_INT >= 21) { 590a6b67f8cbb80323786f7e5d9db442f080e242d76Aurimas Liutikas view.animate().translationZ(value); 591a6b67f8cbb80323786f7e5d9db442f080e242d76Aurimas Liutikas } 592e322b8bcc717dfd663677ed5cb59c6d1c3cb27afChris Banes } 593e322b8bcc717dfd663677ed5cb59c6d1c3cb27afChris Banes return this; 594e322b8bcc717dfd663677ed5cb59c6d1c3cb27afChris Banes } 595e322b8bcc717dfd663677ed5cb59c6d1c3cb27afChris Banes 596e322b8bcc717dfd663677ed5cb59c6d1c3cb27afChris Banes /** 597e322b8bcc717dfd663677ed5cb59c6d1c3cb27afChris Banes * This method will cause the View's <code>z</code> property to be animated to the 598e322b8bcc717dfd663677ed5cb59c6d1c3cb27afChris Banes * specified value. Animations already running on the property will be canceled. 599e322b8bcc717dfd663677ed5cb59c6d1c3cb27afChris Banes * 600e322b8bcc717dfd663677ed5cb59c6d1c3cb27afChris Banes * <p>Prior to API 21, this method will do nothing.</p> 601e322b8bcc717dfd663677ed5cb59c6d1c3cb27afChris Banes * 602e322b8bcc717dfd663677ed5cb59c6d1c3cb27afChris Banes * @param value The amount to be animated by, as an offset from the current value. 603e322b8bcc717dfd663677ed5cb59c6d1c3cb27afChris Banes * @return This object, allowing calls to methods in this class to be chained. 604e322b8bcc717dfd663677ed5cb59c6d1c3cb27afChris Banes */ 605e322b8bcc717dfd663677ed5cb59c6d1c3cb27afChris Banes public ViewPropertyAnimatorCompat z(float value) { 606e322b8bcc717dfd663677ed5cb59c6d1c3cb27afChris Banes View view; 607e322b8bcc717dfd663677ed5cb59c6d1c3cb27afChris Banes if ((view = mView.get()) != null) { 608a6b67f8cbb80323786f7e5d9db442f080e242d76Aurimas Liutikas if (Build.VERSION.SDK_INT >= 21) { 609a6b67f8cbb80323786f7e5d9db442f080e242d76Aurimas Liutikas view.animate().z(value); 610a6b67f8cbb80323786f7e5d9db442f080e242d76Aurimas Liutikas } 611e322b8bcc717dfd663677ed5cb59c6d1c3cb27afChris Banes } 612e322b8bcc717dfd663677ed5cb59c6d1c3cb27afChris Banes return this; 613e322b8bcc717dfd663677ed5cb59c6d1c3cb27afChris Banes } 614e322b8bcc717dfd663677ed5cb59c6d1c3cb27afChris Banes 615e322b8bcc717dfd663677ed5cb59c6d1c3cb27afChris Banes /** 616e322b8bcc717dfd663677ed5cb59c6d1c3cb27afChris Banes * This method will cause the View's <code>z</code> property to be animated by the 617e322b8bcc717dfd663677ed5cb59c6d1c3cb27afChris Banes * specified value. Animations already running on the property will be canceled. 618e322b8bcc717dfd663677ed5cb59c6d1c3cb27afChris Banes * 619e322b8bcc717dfd663677ed5cb59c6d1c3cb27afChris Banes * <p>Prior to API 21, this method will do nothing.</p> 620e322b8bcc717dfd663677ed5cb59c6d1c3cb27afChris Banes * 621e322b8bcc717dfd663677ed5cb59c6d1c3cb27afChris Banes * @param value The amount to be animated by, as an offset from the current value. 622e322b8bcc717dfd663677ed5cb59c6d1c3cb27afChris Banes * @return This object, allowing calls to methods in this class to be chained. 623e322b8bcc717dfd663677ed5cb59c6d1c3cb27afChris Banes */ 624e322b8bcc717dfd663677ed5cb59c6d1c3cb27afChris Banes public ViewPropertyAnimatorCompat zBy(float value) { 625e322b8bcc717dfd663677ed5cb59c6d1c3cb27afChris Banes View view; 626e322b8bcc717dfd663677ed5cb59c6d1c3cb27afChris Banes if ((view = mView.get()) != null) { 627a6b67f8cbb80323786f7e5d9db442f080e242d76Aurimas Liutikas if (Build.VERSION.SDK_INT >= 21) { 628a6b67f8cbb80323786f7e5d9db442f080e242d76Aurimas Liutikas view.animate().zBy(value); 629a6b67f8cbb80323786f7e5d9db442f080e242d76Aurimas Liutikas } 630e322b8bcc717dfd663677ed5cb59c6d1c3cb27afChris Banes } 631e322b8bcc717dfd663677ed5cb59c6d1c3cb27afChris Banes return this; 632e322b8bcc717dfd663677ed5cb59c6d1c3cb27afChris Banes } 633e322b8bcc717dfd663677ed5cb59c6d1c3cb27afChris Banes 634e322b8bcc717dfd663677ed5cb59c6d1c3cb27afChris Banes /** 635d7d27e9ebe5c7325e67e1a8af265378bd2056cadChet Haase * Starts the currently pending property animations immediately. Calling <code>start()</code> 636d7d27e9ebe5c7325e67e1a8af265378bd2056cadChet Haase * is optional because all animations start automatically at the next opportunity. However, 637d7d27e9ebe5c7325e67e1a8af265378bd2056cadChet Haase * if the animations are needed to start immediately and synchronously (not at the time when 638d7d27e9ebe5c7325e67e1a8af265378bd2056cadChet Haase * the next event is processed by the hierarchy, which is when the animations would begin 639d7d27e9ebe5c7325e67e1a8af265378bd2056cadChet Haase * otherwise), then this method can be used. 640d7d27e9ebe5c7325e67e1a8af265378bd2056cadChet Haase */ 641d7d27e9ebe5c7325e67e1a8af265378bd2056cadChet Haase public void start() { 642d7d27e9ebe5c7325e67e1a8af265378bd2056cadChet Haase View view; 643d7d27e9ebe5c7325e67e1a8af265378bd2056cadChet Haase if ((view = mView.get()) != null) { 644846955fba824b96d8cca48e372353d5b7cc31955Aurimas Liutikas view.animate().start(); 645d7d27e9ebe5c7325e67e1a8af265378bd2056cadChet Haase } 646d7d27e9ebe5c7325e67e1a8af265378bd2056cadChet Haase } 647d7d27e9ebe5c7325e67e1a8af265378bd2056cadChet Haase 648d7d27e9ebe5c7325e67e1a8af265378bd2056cadChet Haase /** 649d7d27e9ebe5c7325e67e1a8af265378bd2056cadChet Haase * The View associated with this ViewPropertyAnimator will have its 650fa0f82f629bf95681c14ed559922f77a3030aa18Aurimas Liutikas * {@link View#setLayerType(int, android.graphics.Paint) layer type} set to 651fa0f82f629bf95681c14ed559922f77a3030aa18Aurimas Liutikas * {@link View#LAYER_TYPE_HARDWARE} for the duration of the next animation. 652fa0f82f629bf95681c14ed559922f77a3030aa18Aurimas Liutikas * As stated in the documentation for {@link View#LAYER_TYPE_HARDWARE}, 653d7d27e9ebe5c7325e67e1a8af265378bd2056cadChet Haase * the actual type of layer used internally depends on the runtime situation of the 654d7d27e9ebe5c7325e67e1a8af265378bd2056cadChet Haase * view. If the activity and this view are hardware-accelerated, then the layer will be 655d7d27e9ebe5c7325e67e1a8af265378bd2056cadChet Haase * accelerated as well. If the activity or the view is not accelerated, then the layer will 656fa0f82f629bf95681c14ed559922f77a3030aa18Aurimas Liutikas * effectively be the same as {@link View#LAYER_TYPE_SOFTWARE}. 657d7d27e9ebe5c7325e67e1a8af265378bd2056cadChet Haase * 658d7d27e9ebe5c7325e67e1a8af265378bd2056cadChet Haase * <p>This state is not persistent, either on the View or on this ViewPropertyAnimator: the 659d7d27e9ebe5c7325e67e1a8af265378bd2056cadChet Haase * layer type of the View will be restored when the animation ends to what it was when this 660d7d27e9ebe5c7325e67e1a8af265378bd2056cadChet Haase * method was called, and this setting on ViewPropertyAnimator is only valid for the next 661d7d27e9ebe5c7325e67e1a8af265378bd2056cadChet Haase * animation. Note that calling this method and then independently setting the layer type of 662d7d27e9ebe5c7325e67e1a8af265378bd2056cadChet Haase * the View (by a direct call to 663fa0f82f629bf95681c14ed559922f77a3030aa18Aurimas Liutikas * {@link View#setLayerType(int, android.graphics.Paint)}) will result in some 664d7d27e9ebe5c7325e67e1a8af265378bd2056cadChet Haase * inconsistency, including having the layer type restored to its pre-withLayer() 665d7d27e9ebe5c7325e67e1a8af265378bd2056cadChet Haase * value when the animation ends.</p> 666d7d27e9ebe5c7325e67e1a8af265378bd2056cadChet Haase * 667d7d27e9ebe5c7325e67e1a8af265378bd2056cadChet Haase * <p>For API 14 and 15, this method will run by setting 668d7d27e9ebe5c7325e67e1a8af265378bd2056cadChet Haase * a listener on the ViewPropertyAnimatorCompat object, setting a hardware layer in 669d7d27e9ebe5c7325e67e1a8af265378bd2056cadChet Haase * the listener's {@link ViewPropertyAnimatorListener#onAnimationStart(View)} method, 670d7d27e9ebe5c7325e67e1a8af265378bd2056cadChet Haase * and then restoring the orignal layer type in the listener's 671d7d27e9ebe5c7325e67e1a8af265378bd2056cadChet Haase * {@link ViewPropertyAnimatorListener#onAnimationEnd(View)} method.</p> 672d7d27e9ebe5c7325e67e1a8af265378bd2056cadChet Haase * 673d7d27e9ebe5c7325e67e1a8af265378bd2056cadChet Haase * @see View#setLayerType(int, android.graphics.Paint) 674d7d27e9ebe5c7325e67e1a8af265378bd2056cadChet Haase * @return This object, allowing calls to methods in this class to be chained. 675d7d27e9ebe5c7325e67e1a8af265378bd2056cadChet Haase */ 676d7d27e9ebe5c7325e67e1a8af265378bd2056cadChet Haase public ViewPropertyAnimatorCompat withLayer() { 677d7d27e9ebe5c7325e67e1a8af265378bd2056cadChet Haase View view; 678d7d27e9ebe5c7325e67e1a8af265378bd2056cadChet Haase if ((view = mView.get()) != null) { 679a6b67f8cbb80323786f7e5d9db442f080e242d76Aurimas Liutikas if (Build.VERSION.SDK_INT >= 16) { 680a6b67f8cbb80323786f7e5d9db442f080e242d76Aurimas Liutikas view.animate().withLayer(); 681a6b67f8cbb80323786f7e5d9db442f080e242d76Aurimas Liutikas } else { 682a6b67f8cbb80323786f7e5d9db442f080e242d76Aurimas Liutikas mOldLayerType = view.getLayerType(); 683a6b67f8cbb80323786f7e5d9db442f080e242d76Aurimas Liutikas setListenerInternal(view, new ViewPropertyAnimatorListenerApi14(this)); 684a6b67f8cbb80323786f7e5d9db442f080e242d76Aurimas Liutikas } 685d7d27e9ebe5c7325e67e1a8af265378bd2056cadChet Haase } 686d7d27e9ebe5c7325e67e1a8af265378bd2056cadChet Haase return this; 687d7d27e9ebe5c7325e67e1a8af265378bd2056cadChet Haase } 688d7d27e9ebe5c7325e67e1a8af265378bd2056cadChet Haase 689d7d27e9ebe5c7325e67e1a8af265378bd2056cadChet Haase /** 690d7d27e9ebe5c7325e67e1a8af265378bd2056cadChet Haase * Specifies an action to take place when the next animation runs. If there is a 691d7d27e9ebe5c7325e67e1a8af265378bd2056cadChet Haase * {@link #setStartDelay(long) startDelay} set on this ViewPropertyAnimator, then the 692d7d27e9ebe5c7325e67e1a8af265378bd2056cadChet Haase * action will run after that startDelay expires, when the actual animation begins. 693d7d27e9ebe5c7325e67e1a8af265378bd2056cadChet Haase * This method, along with {@link #withEndAction(Runnable)}, is intended to help facilitate 694d7d27e9ebe5c7325e67e1a8af265378bd2056cadChet Haase * choreographing ViewPropertyAnimator animations with other animations or actions 695d7d27e9ebe5c7325e67e1a8af265378bd2056cadChet Haase * in the application. 696d7d27e9ebe5c7325e67e1a8af265378bd2056cadChet Haase * 697d7d27e9ebe5c7325e67e1a8af265378bd2056cadChet Haase * <p>For API 14 and 15, this method will run by setting 698d7d27e9ebe5c7325e67e1a8af265378bd2056cadChet Haase * a listener on the ViewPropertyAnimatorCompat object and running the action 699d7d27e9ebe5c7325e67e1a8af265378bd2056cadChet Haase * in that listener's {@link ViewPropertyAnimatorListener#onAnimationStart(View)} method.</p> 700d7d27e9ebe5c7325e67e1a8af265378bd2056cadChet Haase * 701d7d27e9ebe5c7325e67e1a8af265378bd2056cadChet Haase * @param runnable The action to run when the next animation starts. 702d7d27e9ebe5c7325e67e1a8af265378bd2056cadChet Haase * @return This object, allowing calls to methods in this class to be chained. 703d7d27e9ebe5c7325e67e1a8af265378bd2056cadChet Haase */ 704d7d27e9ebe5c7325e67e1a8af265378bd2056cadChet Haase public ViewPropertyAnimatorCompat withStartAction(Runnable runnable) { 705d7d27e9ebe5c7325e67e1a8af265378bd2056cadChet Haase View view; 706d7d27e9ebe5c7325e67e1a8af265378bd2056cadChet Haase if ((view = mView.get()) != null) { 707a6b67f8cbb80323786f7e5d9db442f080e242d76Aurimas Liutikas if (Build.VERSION.SDK_INT >= 16) { 708a6b67f8cbb80323786f7e5d9db442f080e242d76Aurimas Liutikas view.animate().withStartAction(runnable); 709a6b67f8cbb80323786f7e5d9db442f080e242d76Aurimas Liutikas } else { 710a6b67f8cbb80323786f7e5d9db442f080e242d76Aurimas Liutikas setListenerInternal(view, new ViewPropertyAnimatorListenerApi14(this)); 711a6b67f8cbb80323786f7e5d9db442f080e242d76Aurimas Liutikas mStartAction = runnable; 712a6b67f8cbb80323786f7e5d9db442f080e242d76Aurimas Liutikas } 713d7d27e9ebe5c7325e67e1a8af265378bd2056cadChet Haase } 714d7d27e9ebe5c7325e67e1a8af265378bd2056cadChet Haase return this; 715d7d27e9ebe5c7325e67e1a8af265378bd2056cadChet Haase } 716d7d27e9ebe5c7325e67e1a8af265378bd2056cadChet Haase 717d7d27e9ebe5c7325e67e1a8af265378bd2056cadChet Haase /** 718d7d27e9ebe5c7325e67e1a8af265378bd2056cadChet Haase * Sets a listener for events in the underlying Animators that run the property 719d7d27e9ebe5c7325e67e1a8af265378bd2056cadChet Haase * animations. 720d7d27e9ebe5c7325e67e1a8af265378bd2056cadChet Haase * 721d7d27e9ebe5c7325e67e1a8af265378bd2056cadChet Haase * @param listener The listener to be called with AnimatorListener events. A value of 722d7d27e9ebe5c7325e67e1a8af265378bd2056cadChet Haase * <code>null</code> removes any existing listener. 723d7d27e9ebe5c7325e67e1a8af265378bd2056cadChet Haase * @return This object, allowing calls to methods in this class to be chained. 724d7d27e9ebe5c7325e67e1a8af265378bd2056cadChet Haase */ 725a6b67f8cbb80323786f7e5d9db442f080e242d76Aurimas Liutikas public ViewPropertyAnimatorCompat setListener(final ViewPropertyAnimatorListener listener) { 726a6b67f8cbb80323786f7e5d9db442f080e242d76Aurimas Liutikas final View view; 727d7d27e9ebe5c7325e67e1a8af265378bd2056cadChet Haase if ((view = mView.get()) != null) { 728a6b67f8cbb80323786f7e5d9db442f080e242d76Aurimas Liutikas if (Build.VERSION.SDK_INT >= 16) { 729a6b67f8cbb80323786f7e5d9db442f080e242d76Aurimas Liutikas setListenerInternal(view, listener); 730a6b67f8cbb80323786f7e5d9db442f080e242d76Aurimas Liutikas } else { 731a6b67f8cbb80323786f7e5d9db442f080e242d76Aurimas Liutikas view.setTag(LISTENER_TAG_ID, listener); 732a6b67f8cbb80323786f7e5d9db442f080e242d76Aurimas Liutikas setListenerInternal(view, new ViewPropertyAnimatorListenerApi14(this)); 733a6b67f8cbb80323786f7e5d9db442f080e242d76Aurimas Liutikas } 734d7d27e9ebe5c7325e67e1a8af265378bd2056cadChet Haase } 735d7d27e9ebe5c7325e67e1a8af265378bd2056cadChet Haase return this; 736d7d27e9ebe5c7325e67e1a8af265378bd2056cadChet Haase } 73749c78900da0d43140fb602431fb93212bd7f6c70Chris Banes 738a6b67f8cbb80323786f7e5d9db442f080e242d76Aurimas Liutikas private void setListenerInternal(final View view, final ViewPropertyAnimatorListener listener) { 739a6b67f8cbb80323786f7e5d9db442f080e242d76Aurimas Liutikas if (listener != null) { 740a6b67f8cbb80323786f7e5d9db442f080e242d76Aurimas Liutikas view.animate().setListener(new AnimatorListenerAdapter() { 741a6b67f8cbb80323786f7e5d9db442f080e242d76Aurimas Liutikas @Override 742a6b67f8cbb80323786f7e5d9db442f080e242d76Aurimas Liutikas public void onAnimationCancel(Animator animation) { 743a6b67f8cbb80323786f7e5d9db442f080e242d76Aurimas Liutikas listener.onAnimationCancel(view); 744a6b67f8cbb80323786f7e5d9db442f080e242d76Aurimas Liutikas } 745a6b67f8cbb80323786f7e5d9db442f080e242d76Aurimas Liutikas 746a6b67f8cbb80323786f7e5d9db442f080e242d76Aurimas Liutikas @Override 747a6b67f8cbb80323786f7e5d9db442f080e242d76Aurimas Liutikas public void onAnimationEnd(Animator animation) { 748a6b67f8cbb80323786f7e5d9db442f080e242d76Aurimas Liutikas listener.onAnimationEnd(view); 749a6b67f8cbb80323786f7e5d9db442f080e242d76Aurimas Liutikas } 750a6b67f8cbb80323786f7e5d9db442f080e242d76Aurimas Liutikas 751a6b67f8cbb80323786f7e5d9db442f080e242d76Aurimas Liutikas @Override 752a6b67f8cbb80323786f7e5d9db442f080e242d76Aurimas Liutikas public void onAnimationStart(Animator animation) { 753a6b67f8cbb80323786f7e5d9db442f080e242d76Aurimas Liutikas listener.onAnimationStart(view); 754a6b67f8cbb80323786f7e5d9db442f080e242d76Aurimas Liutikas } 755a6b67f8cbb80323786f7e5d9db442f080e242d76Aurimas Liutikas }); 756a6b67f8cbb80323786f7e5d9db442f080e242d76Aurimas Liutikas } else { 757a6b67f8cbb80323786f7e5d9db442f080e242d76Aurimas Liutikas view.animate().setListener(null); 758a6b67f8cbb80323786f7e5d9db442f080e242d76Aurimas Liutikas } 759a6b67f8cbb80323786f7e5d9db442f080e242d76Aurimas Liutikas } 760a6b67f8cbb80323786f7e5d9db442f080e242d76Aurimas Liutikas 76149c78900da0d43140fb602431fb93212bd7f6c70Chris Banes /** 76249c78900da0d43140fb602431fb93212bd7f6c70Chris Banes * Sets a listener for update events in the underlying Animator that runs 76349c78900da0d43140fb602431fb93212bd7f6c70Chris Banes * the property animations. 76449c78900da0d43140fb602431fb93212bd7f6c70Chris Banes * 76549c78900da0d43140fb602431fb93212bd7f6c70Chris Banes * <p>Prior to API 19, this method will do nothing.</p> 76649c78900da0d43140fb602431fb93212bd7f6c70Chris Banes * 76749c78900da0d43140fb602431fb93212bd7f6c70Chris Banes * @param listener The listener to be called with update events. A value of 76849c78900da0d43140fb602431fb93212bd7f6c70Chris Banes * <code>null</code> removes any existing listener. 76949c78900da0d43140fb602431fb93212bd7f6c70Chris Banes * @return This object, allowing calls to methods in this class to be chained. 77049c78900da0d43140fb602431fb93212bd7f6c70Chris Banes */ 77149c78900da0d43140fb602431fb93212bd7f6c70Chris Banes public ViewPropertyAnimatorCompat setUpdateListener( 772a6b67f8cbb80323786f7e5d9db442f080e242d76Aurimas Liutikas final ViewPropertyAnimatorUpdateListener listener) { 773a6b67f8cbb80323786f7e5d9db442f080e242d76Aurimas Liutikas final View view; 77449c78900da0d43140fb602431fb93212bd7f6c70Chris Banes if ((view = mView.get()) != null) { 775a6b67f8cbb80323786f7e5d9db442f080e242d76Aurimas Liutikas if (Build.VERSION.SDK_INT >= 19) { 776a6b67f8cbb80323786f7e5d9db442f080e242d76Aurimas Liutikas ValueAnimator.AnimatorUpdateListener wrapped = null; 777a6b67f8cbb80323786f7e5d9db442f080e242d76Aurimas Liutikas if (listener != null) { 778a6b67f8cbb80323786f7e5d9db442f080e242d76Aurimas Liutikas wrapped = new ValueAnimator.AnimatorUpdateListener() { 779a6b67f8cbb80323786f7e5d9db442f080e242d76Aurimas Liutikas @Override 780a6b67f8cbb80323786f7e5d9db442f080e242d76Aurimas Liutikas public void onAnimationUpdate(ValueAnimator valueAnimator) { 781a6b67f8cbb80323786f7e5d9db442f080e242d76Aurimas Liutikas listener.onAnimationUpdate(view); 782a6b67f8cbb80323786f7e5d9db442f080e242d76Aurimas Liutikas } 783a6b67f8cbb80323786f7e5d9db442f080e242d76Aurimas Liutikas }; 784a6b67f8cbb80323786f7e5d9db442f080e242d76Aurimas Liutikas } 785a6b67f8cbb80323786f7e5d9db442f080e242d76Aurimas Liutikas view.animate().setUpdateListener(wrapped); 786a6b67f8cbb80323786f7e5d9db442f080e242d76Aurimas Liutikas } 78749c78900da0d43140fb602431fb93212bd7f6c70Chris Banes } 78849c78900da0d43140fb602431fb93212bd7f6c70Chris Banes return this; 78949c78900da0d43140fb602431fb93212bd7f6c70Chris Banes } 790d7d27e9ebe5c7325e67e1a8af265378bd2056cadChet Haase} 791