public final class

ViewPropertyAnimatorCompat

extends java.lang.Object

 java.lang.Object

↳androidx.core.view.ViewPropertyAnimatorCompat

Gradle dependencies

compile group: 'androidx.core', name: 'core', version: '1.9.0-alpha04'

  • groupId: androidx.core
  • artifactId: core
  • version: 1.9.0-alpha04

Artifact androidx.core:core:1.9.0-alpha04 it located at Google repository (https://maven.google.com/)

Androidx artifact mapping:

androidx.core:core com.android.support:support-compat

Androidx class mapping:

androidx.core.view.ViewPropertyAnimatorCompat android.support.v4.view.ViewPropertyAnimatorCompat

Summary

Methods
public ViewPropertyAnimatorCompatalpha(float value)

This method will cause the View's alpha property to be animated to the specified value.

public ViewPropertyAnimatorCompatalphaBy(float value)

This method will cause the View's alpha property to be animated by the specified value.

public voidcancel()

Cancels all property animations that are currently running or pending.

public longgetDuration()

Returns the current duration of property animations.

public InterpolatorgetInterpolator()

Returns the timing interpolator that this animation uses.

public longgetStartDelay()

Returns the current startDelay of property animations.

public ViewPropertyAnimatorCompatrotation(float value)

This method will cause the View's rotation property to be animated to the specified value.

public ViewPropertyAnimatorCompatrotationBy(float value)

This method will cause the View's rotation property to be animated by the specified value.

public ViewPropertyAnimatorCompatrotationX(float value)

This method will cause the View's rotationX property to be animated to the specified value.

public ViewPropertyAnimatorCompatrotationXBy(float value)

This method will cause the View's rotationX property to be animated by the specified value.

public ViewPropertyAnimatorCompatrotationY(float value)

This method will cause the View's rotationY property to be animated to the specified value.

public ViewPropertyAnimatorCompatrotationYBy(float value)

This method will cause the View's rotationY property to be animated by the specified value.

public ViewPropertyAnimatorCompatscaleX(float value)

This method will cause the View's scaleX property to be animated to the specified value.

public ViewPropertyAnimatorCompatscaleXBy(float value)

This method will cause the View's scaleX property to be animated by the specified value.

public ViewPropertyAnimatorCompatscaleY(float value)

This method will cause the View's scaleY property to be animated to the specified value.

public ViewPropertyAnimatorCompatscaleYBy(float value)

This method will cause the View's scaleY property to be animated by the specified value.

public ViewPropertyAnimatorCompatsetDuration(long value)

Sets the duration for the underlying animator that animates the requested properties.

public ViewPropertyAnimatorCompatsetInterpolator(Interpolator value)

Sets the interpolator for the underlying animator that animates the requested properties.

public ViewPropertyAnimatorCompatsetListener(ViewPropertyAnimatorListener listener)

Sets a listener for events in the underlying Animators that run the property animations.

public ViewPropertyAnimatorCompatsetStartDelay(long value)

Sets the startDelay for the underlying animator that animates the requested properties.

public ViewPropertyAnimatorCompatsetUpdateListener(ViewPropertyAnimatorUpdateListener listener)

Sets a listener for update events in the underlying Animator that runs the property animations.

public voidstart()

Starts the currently pending property animations immediately.

public ViewPropertyAnimatorCompattranslationX(float value)

This method will cause the View's translationX property to be animated to the specified value.

public ViewPropertyAnimatorCompattranslationXBy(float value)

This method will cause the View's translationX property to be animated by the specified value.

public ViewPropertyAnimatorCompattranslationY(float value)

This method will cause the View's translationY property to be animated to the specified value.

public ViewPropertyAnimatorCompattranslationYBy(float value)

This method will cause the View's translationY property to be animated by the specified value.

public ViewPropertyAnimatorCompattranslationZ(float value)

This method will cause the View's translationZ property to be animated to the specified value.

public ViewPropertyAnimatorCompattranslationZBy(float value)

This method will cause the View's translationZ property to be animated by the specified value.

public ViewPropertyAnimatorCompatwithEndAction(java.lang.Runnable runnable)

Specifies an action to take place when the next animation ends.

public ViewPropertyAnimatorCompatwithLayer()

The View associated with this ViewPropertyAnimator will have its layer type set to View for the duration of the next animation.

public ViewPropertyAnimatorCompatwithStartAction(java.lang.Runnable runnable)

Specifies an action to take place when the next animation runs.

public ViewPropertyAnimatorCompatx(float value)

This method will cause the View's x property to be animated to the specified value.

public ViewPropertyAnimatorCompatxBy(float value)

This method will cause the View's x property to be animated by the specified value.

public ViewPropertyAnimatorCompaty(float value)

This method will cause the View's y property to be animated to the specified value.

public ViewPropertyAnimatorCompatyBy(float value)

This method will cause the View's y property to be animated by the specified value.

public ViewPropertyAnimatorCompatz(float value)

This method will cause the View's z property to be animated to the specified value.

public ViewPropertyAnimatorCompatzBy(float value)

This method will cause the View's z property to be animated by the specified value.

from java.lang.Objectclone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait

Methods

public ViewPropertyAnimatorCompat setDuration(long value)

Sets the duration for the underlying animator that animates the requested properties. By default, the animator uses the default value for ValueAnimator. Calling this method will cause the declared value to be used instead.

Parameters:

value: The length of ensuing property animations, in milliseconds. The value cannot be negative.

Returns:

This object, allowing calls to methods in this class to be chained.

public ViewPropertyAnimatorCompat alpha(float value)

This method will cause the View's alpha property to be animated to the specified value. Animations already running on the property will be canceled.

Parameters:

value: The value to be animated to.

Returns:

This object, allowing calls to methods in this class to be chained.

public ViewPropertyAnimatorCompat alphaBy(float value)

This method will cause the View's alpha property to be animated by the specified value. Animations already running on the property will be canceled.

Parameters:

value: The amount to be animated by, as an offset from the current value.

Returns:

This object, allowing calls to methods in this class to be chained.

public ViewPropertyAnimatorCompat translationX(float value)

This method will cause the View's translationX property to be animated to the specified value. Animations already running on the property will be canceled.

Parameters:

value: The value to be animated to.

Returns:

This object, allowing calls to methods in this class to be chained.

public ViewPropertyAnimatorCompat translationY(float value)

This method will cause the View's translationY property to be animated to the specified value. Animations already running on the property will be canceled.

Parameters:

value: The value to be animated to.

Returns:

This object, allowing calls to methods in this class to be chained.

public ViewPropertyAnimatorCompat withEndAction(java.lang.Runnable runnable)

Specifies an action to take place when the next animation ends. The action is only run if the animation ends normally; if the ViewPropertyAnimator is canceled during that animation, the runnable will not run. This method, along with ViewPropertyAnimatorCompat.withStartAction(Runnable), is intended to help facilitate choreographing ViewPropertyAnimator animations with other animations or actions in the application.

For example, the following code animates a view to x=200 and then back to 0:

     Runnable endAction = new Runnable() {
         public void run() {
             view.animate().x(0);
         }
     };
     view.animate().x(200).withEndAction(endAction);
 

For API 14 and 15, this method will run by setting a listener on the ViewPropertyAnimatorCompat object and running the action in that listener's ViewPropertyAnimatorListener.onAnimationEnd(View) method.

Parameters:

runnable: The action to run when the next animation ends.

Returns:

This object, allowing calls to methods in this class to be chained.

public long getDuration()

Returns the current duration of property animations. If the duration was set on this object, that value is returned. Otherwise, the default value of the underlying Animator is returned.

Returns:

The duration of animations, in milliseconds.

See also: ViewPropertyAnimatorCompat.setDuration(long)

public ViewPropertyAnimatorCompat setInterpolator(Interpolator value)

Sets the interpolator for the underlying animator that animates the requested properties. By default, the animator uses the default interpolator for ValueAnimator. Calling this method will cause the declared object to be used instead.

Parameters:

value: The TimeInterpolator to be used for ensuing property animations.

Returns:

This object, allowing calls to methods in this class to be chained.

public Interpolator getInterpolator()

Returns the timing interpolator that this animation uses.

Returns:

The timing interpolator for this animation.

public ViewPropertyAnimatorCompat setStartDelay(long value)

Sets the startDelay for the underlying animator that animates the requested properties. By default, the animator uses the default value for ValueAnimator. Calling this method will cause the declared value to be used instead.

Parameters:

value: The delay of ensuing property animations, in milliseconds. The value cannot be negative.

Returns:

This object, allowing calls to methods in this class to be chained.

public long getStartDelay()

Returns the current startDelay of property animations. If the startDelay was set on this object, that value is returned. Otherwise, the default value of the underlying Animator is returned.

Returns:

The startDelay of animations, in milliseconds.

See also: ViewPropertyAnimatorCompat.setStartDelay(long)

public ViewPropertyAnimatorCompat rotation(float value)

This method will cause the View's rotation property to be animated to the specified value. Animations already running on the property will be canceled.

Parameters:

value: The value to be animated to.

Returns:

This object, allowing calls to methods in this class to be chained.

public ViewPropertyAnimatorCompat rotationBy(float value)

This method will cause the View's rotation property to be animated by the specified value. Animations already running on the property will be canceled.

Parameters:

value: The amount to be animated by, as an offset from the current value.

Returns:

This object, allowing calls to methods in this class to be chained.

public ViewPropertyAnimatorCompat rotationX(float value)

This method will cause the View's rotationX property to be animated to the specified value. Animations already running on the property will be canceled.

Parameters:

value: The value to be animated to.

Returns:

This object, allowing calls to methods in this class to be chained.

public ViewPropertyAnimatorCompat rotationXBy(float value)

This method will cause the View's rotationX property to be animated by the specified value. Animations already running on the property will be canceled.

Parameters:

value: The amount to be animated by, as an offset from the current value.

Returns:

This object, allowing calls to methods in this class to be chained.

public ViewPropertyAnimatorCompat rotationY(float value)

This method will cause the View's rotationY property to be animated to the specified value. Animations already running on the property will be canceled.

Parameters:

value: The value to be animated to.

Returns:

This object, allowing calls to methods in this class to be chained.

public ViewPropertyAnimatorCompat rotationYBy(float value)

This method will cause the View's rotationY property to be animated by the specified value. Animations already running on the property will be canceled.

Parameters:

value: The amount to be animated by, as an offset from the current value.

Returns:

This object, allowing calls to methods in this class to be chained.

public ViewPropertyAnimatorCompat scaleX(float value)

This method will cause the View's scaleX property to be animated to the specified value. Animations already running on the property will be canceled.

Parameters:

value: The value to be animated to.

Returns:

This object, allowing calls to methods in this class to be chained.

public ViewPropertyAnimatorCompat scaleXBy(float value)

This method will cause the View's scaleX property to be animated by the specified value. Animations already running on the property will be canceled.

Parameters:

value: The amount to be animated by, as an offset from the current value.

Returns:

This object, allowing calls to methods in this class to be chained.

public ViewPropertyAnimatorCompat scaleY(float value)

This method will cause the View's scaleY property to be animated to the specified value. Animations already running on the property will be canceled.

Parameters:

value: The value to be animated to.

Returns:

This object, allowing calls to methods in this class to be chained.

public ViewPropertyAnimatorCompat scaleYBy(float value)

This method will cause the View's scaleY property to be animated by the specified value. Animations already running on the property will be canceled.

Parameters:

value: The amount to be animated by, as an offset from the current value.

Returns:

This object, allowing calls to methods in this class to be chained.

public void cancel()

Cancels all property animations that are currently running or pending.

public ViewPropertyAnimatorCompat x(float value)

This method will cause the View's x property to be animated to the specified value. Animations already running on the property will be canceled.

Parameters:

value: The value to be animated to.

Returns:

This object, allowing calls to methods in this class to be chained.

public ViewPropertyAnimatorCompat xBy(float value)

This method will cause the View's x property to be animated by the specified value. Animations already running on the property will be canceled.

Parameters:

value: The amount to be animated by, as an offset from the current value.

Returns:

This object, allowing calls to methods in this class to be chained.

public ViewPropertyAnimatorCompat y(float value)

This method will cause the View's y property to be animated to the specified value. Animations already running on the property will be canceled.

Parameters:

value: The value to be animated to.

Returns:

This object, allowing calls to methods in this class to be chained.

public ViewPropertyAnimatorCompat yBy(float value)

This method will cause the View's y property to be animated by the specified value. Animations already running on the property will be canceled.

Parameters:

value: The amount to be animated by, as an offset from the current value.

Returns:

This object, allowing calls to methods in this class to be chained.

public ViewPropertyAnimatorCompat translationXBy(float value)

This method will cause the View's translationX property to be animated by the specified value. Animations already running on the property will be canceled.

Parameters:

value: The amount to be animated by, as an offset from the current value.

Returns:

This object, allowing calls to methods in this class to be chained.

public ViewPropertyAnimatorCompat translationYBy(float value)

This method will cause the View's translationY property to be animated by the specified value. Animations already running on the property will be canceled.

Parameters:

value: The amount to be animated by, as an offset from the current value.

Returns:

This object, allowing calls to methods in this class to be chained.

public ViewPropertyAnimatorCompat translationZBy(float value)

This method will cause the View's translationZ property to be animated by the specified value. Animations already running on the property will be canceled.

Prior to API 21, this method will do nothing.

Parameters:

value: The amount to be animated by, as an offset from the current value.

Returns:

This object, allowing calls to methods in this class to be chained.

public ViewPropertyAnimatorCompat translationZ(float value)

This method will cause the View's translationZ property to be animated to the specified value. Animations already running on the property will be canceled.

Prior to API 21, this method will do nothing.

Parameters:

value: The amount to be animated by, as an offset from the current value.

Returns:

This object, allowing calls to methods in this class to be chained.

public ViewPropertyAnimatorCompat z(float value)

This method will cause the View's z property to be animated to the specified value. Animations already running on the property will be canceled.

Prior to API 21, this method will do nothing.

Parameters:

value: The amount to be animated by, as an offset from the current value.

Returns:

This object, allowing calls to methods in this class to be chained.

public ViewPropertyAnimatorCompat zBy(float value)

This method will cause the View's z property to be animated by the specified value. Animations already running on the property will be canceled.

Prior to API 21, this method will do nothing.

Parameters:

value: The amount to be animated by, as an offset from the current value.

Returns:

This object, allowing calls to methods in this class to be chained.

public void start()

Starts the currently pending property animations immediately. Calling start() is optional because all animations start automatically at the next opportunity. However, if the animations are needed to start immediately and synchronously (not at the time when the next event is processed by the hierarchy, which is when the animations would begin otherwise), then this method can be used.

public ViewPropertyAnimatorCompat withLayer()

The View associated with this ViewPropertyAnimator will have its layer type set to View for the duration of the next animation. As stated in the documentation for View, the actual type of layer used internally depends on the runtime situation of the view. If the activity and this view are hardware-accelerated, then the layer will be accelerated as well. If the activity or the view is not accelerated, then the layer will effectively be the same as View.

This state is not persistent, either on the View or on this ViewPropertyAnimator: the layer type of the View will be restored when the animation ends to what it was when this method was called, and this setting on ViewPropertyAnimator is only valid for the next animation. Note that calling this method and then independently setting the layer type of the View (by a direct call to View) will result in some inconsistency, including having the layer type restored to its pre-withLayer() value when the animation ends.

For API 14 and 15, this method will run by setting a listener on the ViewPropertyAnimatorCompat object, setting a hardware layer in the listener's ViewPropertyAnimatorListener.onAnimationStart(View) method, and then restoring the orignal layer type in the listener's ViewPropertyAnimatorListener.onAnimationEnd(View) method.

Returns:

This object, allowing calls to methods in this class to be chained.

See also: View

public ViewPropertyAnimatorCompat withStartAction(java.lang.Runnable runnable)

Specifies an action to take place when the next animation runs. If there is a startDelay set on this ViewPropertyAnimator, then the action will run after that startDelay expires, when the actual animation begins. This method, along with ViewPropertyAnimatorCompat.withEndAction(Runnable), is intended to help facilitate choreographing ViewPropertyAnimator animations with other animations or actions in the application.

For API 14 and 15, this method will run by setting a listener on the ViewPropertyAnimatorCompat object and running the action in that listener's ViewPropertyAnimatorListener.onAnimationStart(View) method.

Parameters:

runnable: The action to run when the next animation starts.

Returns:

This object, allowing calls to methods in this class to be chained.

Sets a listener for events in the underlying Animators that run the property animations.

Parameters:

listener: The listener to be called with AnimatorListener events. A value of null removes any existing listener.

Returns:

This object, allowing calls to methods in this class to be chained.

Sets a listener for update events in the underlying Animator that runs the property animations.

Prior to API 19, this method will do nothing.

Parameters:

listener: The listener to be called with update events. A value of null removes any existing listener.

Returns:

This object, allowing calls to methods in this class to be chained.

Source

/*
 * Copyright 2018 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package androidx.core.view;

import android.animation.Animator;
import android.animation.AnimatorListenerAdapter;
import android.animation.ValueAnimator;
import android.annotation.SuppressLint;
import android.graphics.Paint;
import android.os.Build;
import android.view.View;
import android.view.ViewPropertyAnimator;
import android.view.animation.Interpolator;

import androidx.annotation.DoNotInline;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.annotation.RequiresApi;

import java.lang.ref.WeakReference;

public final class ViewPropertyAnimatorCompat {
    private final WeakReference<View> mView;

    Runnable mStartAction = null;
    Runnable mEndAction = null;
    int mOldLayerType = -1;
    // HACK ALERT! Choosing this id knowing that the framework does not use it anywhere
    // internally and apps should use ids higher than it
    static final int LISTENER_TAG_ID = 0x7e000000;

    ViewPropertyAnimatorCompat(View view) {
        mView = new WeakReference<>(view);
    }

    static class ViewPropertyAnimatorListenerApi14 implements ViewPropertyAnimatorListener {
        ViewPropertyAnimatorCompat mVpa;
        boolean mAnimEndCalled;

        ViewPropertyAnimatorListenerApi14(ViewPropertyAnimatorCompat vpa) {
            mVpa = vpa;
        }

        @Override
        public void onAnimationStart(@NonNull View view) {
            // Reset our end called flag, since this is a new animation...
            mAnimEndCalled = false;

            if (mVpa.mOldLayerType > -1) {
                view.setLayerType(View.LAYER_TYPE_HARDWARE, null);
            }
            if (mVpa.mStartAction != null) {
                Runnable startAction = mVpa.mStartAction;
                mVpa.mStartAction = null;
                startAction.run();
            }
            Object listenerTag = view.getTag(LISTENER_TAG_ID);
            ViewPropertyAnimatorListener listener = null;
            if (listenerTag instanceof ViewPropertyAnimatorListener) {
                listener = (ViewPropertyAnimatorListener) listenerTag;
            }
            if (listener != null) {
                listener.onAnimationStart(view);
            }
        }

        @Override
        @SuppressLint("WrongConstant")
        public void onAnimationEnd(@NonNull View view) {
            if (mVpa.mOldLayerType > -1) {
                view.setLayerType(mVpa.mOldLayerType, null);
                mVpa.mOldLayerType = -1;
            }
            if (Build.VERSION.SDK_INT >= 16 || !mAnimEndCalled) {
                // Pre-v16 seems to have a bug where onAnimationEnd is called
                // twice, therefore we only dispatch on the first call
                if (mVpa.mEndAction != null) {
                    Runnable endAction = mVpa.mEndAction;
                    mVpa.mEndAction = null;
                    endAction.run();
                }
                Object listenerTag = view.getTag(LISTENER_TAG_ID);
                ViewPropertyAnimatorListener listener = null;
                if (listenerTag instanceof ViewPropertyAnimatorListener) {
                    listener = (ViewPropertyAnimatorListener) listenerTag;
                }
                if (listener != null) {
                    listener.onAnimationEnd(view);
                }
                mAnimEndCalled = true;
            }
        }

        @Override
        public void onAnimationCancel(@NonNull View view) {
            Object listenerTag = view.getTag(LISTENER_TAG_ID);
            ViewPropertyAnimatorListener listener = null;
            if (listenerTag instanceof ViewPropertyAnimatorListener) {
                listener = (ViewPropertyAnimatorListener) listenerTag;
            }
            if (listener != null) {
                listener.onAnimationCancel(view);
            }
        }
    }

    /**
     * Sets the duration for the underlying animator that animates the requested properties.
     * By default, the animator uses the default value for ValueAnimator. Calling this method
     * will cause the declared value to be used instead.
     *
     * @param value The length of ensuing property animations, in milliseconds. The value
     * cannot be negative.
     * @return This object, allowing calls to methods in this class to be chained.
     */
    @NonNull
    public ViewPropertyAnimatorCompat setDuration(long value) {
        View view;
        if ((view = mView.get()) != null) {
            view.animate().setDuration(value);
        }
        return this;
    }

    /**
     * This method will cause the View's <code>alpha</code> property to be animated to the
     * specified value. Animations already running on the property will be canceled.
     *
     * @param value The value to be animated to.
     * @return This object, allowing calls to methods in this class to be chained.
     */
    @NonNull
    public ViewPropertyAnimatorCompat alpha(float value) {
        View view;
        if ((view = mView.get()) != null) {
            view.animate().alpha(value);
        }
        return this;
    }

    /**
     * This method will cause the View's <code>alpha</code> property to be animated by the
     * specified value. Animations already running on the property will be canceled.
     *
     * @param value The amount to be animated by, as an offset from the current value.
     * @return This object, allowing calls to methods in this class to be chained.
     */
    @NonNull
    public ViewPropertyAnimatorCompat alphaBy(float value) {
        View view;
        if ((view = mView.get()) != null) {
            view.animate().alphaBy(value);
        }
        return this;
    }

    /**
     * This method will cause the View's <code>translationX</code> property to be animated to the
     * specified value. Animations already running on the property will be canceled.
     *
     * @param value The value to be animated to.
     * @return This object, allowing calls to methods in this class to be chained.
     */
    @NonNull
    public ViewPropertyAnimatorCompat translationX(float value) {
        View view;
        if ((view = mView.get()) != null) {
            view.animate().translationX(value);
        }
        return this;
    }

    /**
     * This method will cause the View's <code>translationY</code> property to be animated to the
     * specified value. Animations already running on the property will be canceled.
     *
     * @param value The value to be animated to.
     * @return This object, allowing calls to methods in this class to be chained.
     */
    @NonNull
    public ViewPropertyAnimatorCompat translationY(float value) {
        View view;
        if ((view = mView.get()) != null) {
            view.animate().translationY(value);
        }
        return this;
    }

    /**
     * Specifies an action to take place when the next animation ends. The action is only
     * run if the animation ends normally; if the ViewPropertyAnimator is canceled during
     * that animation, the runnable will not run.
     * This method, along with {@link #withStartAction(Runnable)}, is intended to help facilitate
     * choreographing ViewPropertyAnimator animations with other animations or actions
     * in the application.
     *
     * <p>For example, the following code animates a view to x=200 and then back to 0:</p>
     * <pre>
     *     Runnable endAction = new Runnable() {
     *         public void run() {
     *             view.animate().x(0);
     *         }
     *     };
     *     view.animate().x(200).withEndAction(endAction);
     * </pre>
     *
     * <p>For API 14 and 15, this method will run by setting
     * a listener on the ViewPropertyAnimatorCompat object and running the action
     * in that listener's {@link ViewPropertyAnimatorListener#onAnimationEnd(View)} method.</p>
     *
     * @param runnable The action to run when the next animation ends.
     * @return This object, allowing calls to methods in this class to be chained.
     */
    @NonNull
    public ViewPropertyAnimatorCompat withEndAction(@NonNull Runnable runnable) {
        View view;
        if ((view = mView.get()) != null) {
            if (Build.VERSION.SDK_INT >= 16) {
                ViewPropertyAnimator animator = view.animate();
                Api16Impl.withEndAction(animator, runnable);
            } else {
                setListenerInternal(view, new ViewPropertyAnimatorListenerApi14(this));
                mEndAction = runnable;
            }
        }
        return this;
    }

    /**
     * Returns the current duration of property animations. If the duration was set on this
     * object, that value is returned. Otherwise, the default value of the underlying Animator
     * is returned.
     *
     * @see #setDuration(long)
     * @return The duration of animations, in milliseconds.
     */
    public long getDuration() {
        View view;
        if ((view = mView.get()) != null) {
            return view.animate().getDuration();
        } else {
            return 0;
        }
    }

    /**
     * Sets the interpolator for the underlying animator that animates the requested properties.
     * By default, the animator uses the default interpolator for ValueAnimator. Calling this method
     * will cause the declared object to be used instead.
     *
     * @param value The TimeInterpolator to be used for ensuing property animations.
     * @return This object, allowing calls to methods in this class to be chained.
     */
    @NonNull
    public ViewPropertyAnimatorCompat setInterpolator(@Nullable Interpolator value) {
        View view;
        if ((view = mView.get()) != null) {
            view.animate().setInterpolator(value);
        }
        return this;
    }

    /**
     * Returns the timing interpolator that this animation uses.
     *
     * @return The timing interpolator for this animation.
     */
    @Nullable
    public Interpolator getInterpolator() {
        View view;
        if ((view = mView.get()) != null) {
            if (Build.VERSION.SDK_INT >= 18) {
                ViewPropertyAnimator animator = view.animate();
                return Api18Impl.getInterpolator(animator);
            }
        }
        return null;
    }

    /**
     * Sets the startDelay for the underlying animator that animates the requested properties.
     * By default, the animator uses the default value for ValueAnimator. Calling this method
     * will cause the declared value to be used instead.
     *
     * @param value The delay of ensuing property animations, in milliseconds. The value
     * cannot be negative.
     * @return This object, allowing calls to methods in this class to be chained.
     */
    @NonNull
    public ViewPropertyAnimatorCompat setStartDelay(long value) {
        View view;
        if ((view = mView.get()) != null) {
            view.animate().setStartDelay(value);
        }
        return this;
    }

    /**
     * Returns the current startDelay of property animations. If the startDelay was set on this
     * object, that value is returned. Otherwise, the default value of the underlying Animator
     * is returned.
     *
     * @see #setStartDelay(long)
     * @return The startDelay of animations, in milliseconds.
     */
    public long getStartDelay() {
        View view;
        if ((view = mView.get()) != null) {
            return view.animate().getStartDelay();
        } else {
            return 0;
        }
    }

    /**
     * This method will cause the View's <code>rotation</code> property to be animated to the
     * specified value. Animations already running on the property will be canceled.
     *
     * @param value The value to be animated to.
     * @return This object, allowing calls to methods in this class to be chained.
     */
    @NonNull
    public ViewPropertyAnimatorCompat rotation(float value) {
        View view;
        if ((view = mView.get()) != null) {
            view.animate().rotation(value);
        }
        return this;
    }

    /**
     * This method will cause the View's <code>rotation</code> property to be animated by the
     * specified value. Animations already running on the property will be canceled.
     *
     * @param value The amount to be animated by, as an offset from the current value.
     * @return This object, allowing calls to methods in this class to be chained.
     */
    @NonNull
    public ViewPropertyAnimatorCompat rotationBy(float value) {
        View view;
        if ((view = mView.get()) != null) {
            view.animate().rotationBy(value);
        }
        return this;
    }

    /**
     * This method will cause the View's <code>rotationX</code> property to be animated to the
     * specified value. Animations already running on the property will be canceled.
     *
     * @param value The value to be animated to.
     * @return This object, allowing calls to methods in this class to be chained.
     */
    @NonNull
    public ViewPropertyAnimatorCompat rotationX(float value) {
        View view;
        if ((view = mView.get()) != null) {
            view.animate().rotationX(value);
        }
        return this;
    }

    /**
     * This method will cause the View's <code>rotationX</code> property to be animated by the
     * specified value. Animations already running on the property will be canceled.
     *
     * @param value The amount to be animated by, as an offset from the current value.
     * @return This object, allowing calls to methods in this class to be chained.
     */
    @NonNull
    public ViewPropertyAnimatorCompat rotationXBy(float value) {
        View view;
        if ((view = mView.get()) != null) {
            view.animate().rotationXBy(value);
        }
        return this;
    }

    /**
     * This method will cause the View's <code>rotationY</code> property to be animated to the
     * specified value. Animations already running on the property will be canceled.
     *
     * @param value The value to be animated to.
     * @return This object, allowing calls to methods in this class to be chained.
     */
    @NonNull
    public ViewPropertyAnimatorCompat rotationY(float value) {
        View view;
        if ((view = mView.get()) != null) {
            view.animate().rotationY(value);
        }
        return this;
    }

    /**
     * This method will cause the View's <code>rotationY</code> property to be animated by the
     * specified value. Animations already running on the property will be canceled.
     *
     * @param value The amount to be animated by, as an offset from the current value.
     * @return This object, allowing calls to methods in this class to be chained.
     */
    @NonNull
    public ViewPropertyAnimatorCompat rotationYBy(float value) {
        View view;
        if ((view = mView.get()) != null) {
            view.animate().rotationYBy(value);
        }
        return this;
    }

    /**
     * This method will cause the View's <code>scaleX</code> property to be animated to the
     * specified value. Animations already running on the property will be canceled.
     *
     * @param value The value to be animated to.
     * @return This object, allowing calls to methods in this class to be chained.
     */
    @NonNull
    public ViewPropertyAnimatorCompat scaleX(float value) {
        View view;
        if ((view = mView.get()) != null) {
            view.animate().scaleX(value);
        }
        return this;
    }

    /**
     * This method will cause the View's <code>scaleX</code> property to be animated by the
     * specified value. Animations already running on the property will be canceled.
     *
     * @param value The amount to be animated by, as an offset from the current value.
     * @return This object, allowing calls to methods in this class to be chained.
     */
    @NonNull
    public ViewPropertyAnimatorCompat scaleXBy(float value) {
        View view;
        if ((view = mView.get()) != null) {
            view.animate().scaleXBy(value);
        }
        return this;
    }

    /**
     * This method will cause the View's <code>scaleY</code> property to be animated to the
     * specified value. Animations already running on the property will be canceled.
     *
     * @param value The value to be animated to.
     * @return This object, allowing calls to methods in this class to be chained.
     */
    @NonNull
    public ViewPropertyAnimatorCompat scaleY(float value) {
        View view;
        if ((view = mView.get()) != null) {
            view.animate().scaleY(value);
        }
        return this;
    }

    /**
     * This method will cause the View's <code>scaleY</code> property to be animated by the
     * specified value. Animations already running on the property will be canceled.
     *
     * @param value The amount to be animated by, as an offset from the current value.
     * @return This object, allowing calls to methods in this class to be chained.
     */
    @NonNull
    public ViewPropertyAnimatorCompat scaleYBy(float value) {
        View view;
        if ((view = mView.get()) != null) {
            view.animate().scaleYBy(value);
        }
        return this;
    }

    /**
     * Cancels all property animations that are currently running or pending.
     */
    public void cancel() {
        View view;
        if ((view = mView.get()) != null) {
            view.animate().cancel();
        }
    }

    /**
     * This method will cause the View's <code>x</code> property to be animated to the
     * specified value. Animations already running on the property will be canceled.
     *
     * @param value The value to be animated to.
     * @return This object, allowing calls to methods in this class to be chained.
     */
    @NonNull
    public ViewPropertyAnimatorCompat x(float value) {
        View view;
        if ((view = mView.get()) != null) {
            view.animate().x(value);
        }
        return this;
    }

    /**
     * This method will cause the View's <code>x</code> property to be animated by the
     * specified value. Animations already running on the property will be canceled.
     *
     * @param value The amount to be animated by, as an offset from the current value.
     * @return This object, allowing calls to methods in this class to be chained.
     */
    @NonNull
    public ViewPropertyAnimatorCompat xBy(float value) {
        View view;
        if ((view = mView.get()) != null) {
            view.animate().xBy(value);
        }
        return this;
    }

    /**
     * This method will cause the View's <code>y</code> property to be animated to the
     * specified value. Animations already running on the property will be canceled.
     *
     * @param value The value to be animated to.
     * @return This object, allowing calls to methods in this class to be chained.
     */
    @NonNull
    public ViewPropertyAnimatorCompat y(float value) {
        View view;
        if ((view = mView.get()) != null) {
            view.animate().y(value);
        }
        return this;
    }

    /**
     * This method will cause the View's <code>y</code> property to be animated by the
     * specified value. Animations already running on the property will be canceled.
     *
     * @param value The amount to be animated by, as an offset from the current value.
     * @return This object, allowing calls to methods in this class to be chained.
     */
    @NonNull
    public ViewPropertyAnimatorCompat yBy(float value) {
        View view;
        if ((view = mView.get()) != null) {
            view.animate().yBy(value);
        }
        return this;
    }

    /**
     * This method will cause the View's <code>translationX</code> property to be animated by the
     * specified value. Animations already running on the property will be canceled.
     *
     * @param value The amount to be animated by, as an offset from the current value.
     * @return This object, allowing calls to methods in this class to be chained.
     */
    @NonNull
    public ViewPropertyAnimatorCompat translationXBy(float value) {
        View view;
        if ((view = mView.get()) != null) {
            view.animate().translationXBy(value);
        }
        return this;
    }

    /**
     * This method will cause the View's <code>translationY</code> property to be animated by the
     * specified value. Animations already running on the property will be canceled.
     *
     * @param value The amount to be animated by, as an offset from the current value.
     * @return This object, allowing calls to methods in this class to be chained.
     */
    @NonNull
    public ViewPropertyAnimatorCompat translationYBy(float value) {
        View view;
        if ((view = mView.get()) != null) {
            view.animate().translationYBy(value);
        }
        return this;
    }

    /**
     * This method will cause the View's <code>translationZ</code> property to be animated by the
     * specified value. Animations already running on the property will be canceled.
     *
     * <p>Prior to API 21, this method will do nothing.</p>
     *
     * @param value The amount to be animated by, as an offset from the current value.
     * @return This object, allowing calls to methods in this class to be chained.
     */
    @NonNull
    public ViewPropertyAnimatorCompat translationZBy(float value) {
        View view;
        if ((view = mView.get()) != null) {
            if (Build.VERSION.SDK_INT >= 21) {
                ViewPropertyAnimator animator = view.animate();
                Api21Impl.translationZBy(animator, value);
            }
        }
        return this;
    }

    /**
     * This method will cause the View's <code>translationZ</code> property to be animated to the
     * specified value. Animations already running on the property will be canceled.
     *
     * <p>Prior to API 21, this method will do nothing.</p>
     *
     * @param value The amount to be animated by, as an offset from the current value.
     * @return This object, allowing calls to methods in this class to be chained.
     */
    @NonNull
    public ViewPropertyAnimatorCompat translationZ(float value) {
        View view;
        if ((view = mView.get()) != null) {
            if (Build.VERSION.SDK_INT >= 21) {
                ViewPropertyAnimator animator = view.animate();
                Api21Impl.translationZ(animator, value);
            }
        }
        return this;
    }

    /**
     * This method will cause the View's <code>z</code> property to be animated to the
     * specified value. Animations already running on the property will be canceled.
     *
     * <p>Prior to API 21, this method will do nothing.</p>
     *
     * @param value The amount to be animated by, as an offset from the current value.
     * @return This object, allowing calls to methods in this class to be chained.
     */
    @NonNull
    public ViewPropertyAnimatorCompat z(float value) {
        View view;
        if ((view = mView.get()) != null) {
            if (Build.VERSION.SDK_INT >= 21) {
                ViewPropertyAnimator animator = view.animate();
                Api21Impl.z(animator, value);
            }
        }
        return this;
    }

    /**
     * This method will cause the View's <code>z</code> property to be animated by the
     * specified value. Animations already running on the property will be canceled.
     *
     * <p>Prior to API 21, this method will do nothing.</p>
     *
     * @param value The amount to be animated by, as an offset from the current value.
     * @return This object, allowing calls to methods in this class to be chained.
     */
    @NonNull
    public ViewPropertyAnimatorCompat zBy(float value) {
        View view;
        if ((view = mView.get()) != null) {
            if (Build.VERSION.SDK_INT >= 21) {
                ViewPropertyAnimator animator = view.animate();
                Api21Impl.zBy(animator, value);
            }
        }
        return this;
    }

    /**
     * Starts the currently pending property animations immediately. Calling <code>start()</code>
     * is optional because all animations start automatically at the next opportunity. However,
     * if the animations are needed to start immediately and synchronously (not at the time when
     * the next event is processed by the hierarchy, which is when the animations would begin
     * otherwise), then this method can be used.
     */
    public void start() {
        View view;
        if ((view = mView.get()) != null) {
            view.animate().start();
        }
    }

    /**
     * The View associated with this ViewPropertyAnimator will have its
     * {@link View#setLayerType(int, Paint) layer type} set to
     * {@link View#LAYER_TYPE_HARDWARE} for the duration of the next animation.
     * As stated in the documentation for {@link View#LAYER_TYPE_HARDWARE},
     * the actual type of layer used internally depends on the runtime situation of the
     * view. If the activity and this view are hardware-accelerated, then the layer will be
     * accelerated as well. If the activity or the view is not accelerated, then the layer will
     * effectively be the same as {@link View#LAYER_TYPE_SOFTWARE}.
     *
     * <p>This state is not persistent, either on the View or on this ViewPropertyAnimator: the
     * layer type of the View will be restored when the animation ends to what it was when this
     * method was called, and this setting on ViewPropertyAnimator is only valid for the next
     * animation. Note that calling this method and then independently setting the layer type of
     * the View (by a direct call to
     * {@link View#setLayerType(int, Paint)}) will result in some
     * inconsistency, including having the layer type restored to its pre-withLayer()
     * value when the animation ends.</p>
     *
     * <p>For API 14 and 15, this method will run by setting
     * a listener on the ViewPropertyAnimatorCompat object, setting a hardware layer in
     * the listener's {@link ViewPropertyAnimatorListener#onAnimationStart(View)} method,
     * and then restoring the orignal layer type in the listener's
     * {@link ViewPropertyAnimatorListener#onAnimationEnd(View)} method.</p>
     *
     * @see View#setLayerType(int, Paint)
     * @return This object, allowing calls to methods in this class to be chained.
     */
    @NonNull
    @SuppressLint("WrongConstant")
    public ViewPropertyAnimatorCompat withLayer() {
        View view;
        if ((view = mView.get()) != null) {
            if (Build.VERSION.SDK_INT >= 16) {
                ViewPropertyAnimator animator = view.animate();
                Api16Impl.withLayer(animator);
            } else {
                mOldLayerType = view.getLayerType();
                setListenerInternal(view, new ViewPropertyAnimatorListenerApi14(this));
            }
        }
        return this;
    }

    /**
     * Specifies an action to take place when the next animation runs. If there is a
     * {@link #setStartDelay(long) startDelay} set on this ViewPropertyAnimator, then the
     * action will run after that startDelay expires, when the actual animation begins.
     * This method, along with {@link #withEndAction(Runnable)}, is intended to help facilitate
     * choreographing ViewPropertyAnimator animations with other animations or actions
     * in the application.
     *
     * <p>For API 14 and 15, this method will run by setting
     * a listener on the ViewPropertyAnimatorCompat object and running the action
     * in that listener's {@link ViewPropertyAnimatorListener#onAnimationStart(View)} method.</p>
     *
     * @param runnable The action to run when the next animation starts.
     * @return This object, allowing calls to methods in this class to be chained.
     */
    @NonNull
    public ViewPropertyAnimatorCompat withStartAction(@NonNull Runnable runnable) {
        View view;
        if ((view = mView.get()) != null) {
            if (Build.VERSION.SDK_INT >= 16) {
                ViewPropertyAnimator animator = view.animate();
                Api16Impl.withStartAction(animator, runnable);
            } else {
                setListenerInternal(view, new ViewPropertyAnimatorListenerApi14(this));
                mStartAction = runnable;
            }
        }
        return this;
    }

    /**
     * Sets a listener for events in the underlying Animators that run the property
     * animations.
     *
     * @param listener The listener to be called with AnimatorListener events. A value of
     * <code>null</code> removes any existing listener.
     * @return This object, allowing calls to methods in this class to be chained.
     */
    @NonNull
    public ViewPropertyAnimatorCompat setListener(
            final @Nullable ViewPropertyAnimatorListener listener) {
        final View view;
        if ((view = mView.get()) != null) {
            if (Build.VERSION.SDK_INT >= 16) {
                setListenerInternal(view, listener);
            } else {
                view.setTag(LISTENER_TAG_ID, listener);
                setListenerInternal(view, new ViewPropertyAnimatorListenerApi14(this));
            }
        }
        return this;
    }

    private void setListenerInternal(final View view, final ViewPropertyAnimatorListener listener) {
        if (listener != null) {
            view.animate().setListener(new AnimatorListenerAdapter() {
                @Override
                public void onAnimationCancel(Animator animation) {
                    listener.onAnimationCancel(view);
                }

                @Override
                public void onAnimationEnd(Animator animation) {
                    listener.onAnimationEnd(view);
                }

                @Override
                public void onAnimationStart(Animator animation) {
                    listener.onAnimationStart(view);
                }
            });
        } else {
            view.animate().setListener(null);
        }
    }

    /**
     * Sets a listener for update events in the underlying Animator that runs
     * the property animations.
     *
     * <p>Prior to API 19, this method will do nothing.</p>
     *
     * @param listener The listener to be called with update events. A value of
     * <code>null</code> removes any existing listener.
     * @return This object, allowing calls to methods in this class to be chained.
     */
    @NonNull
    public ViewPropertyAnimatorCompat setUpdateListener(
            final @Nullable ViewPropertyAnimatorUpdateListener listener) {
        final View view;
        if ((view = mView.get()) != null) {
            if (Build.VERSION.SDK_INT >= 19) {
                ValueAnimator.AnimatorUpdateListener wrapped = null;
                if (listener != null) {
                    wrapped = valueAnimator -> listener.onAnimationUpdate(view);
                }
                ViewPropertyAnimator animator = view.animate();
                Api19Impl.setUpdateListener(animator, wrapped);
            }
        }
        return this;
    }

    @RequiresApi(16)
    static class Api16Impl {
        private Api16Impl() {
            // This class is not instantiable.
        }

        @DoNotInline
        static ViewPropertyAnimator withEndAction(ViewPropertyAnimator viewPropertyAnimator,
                Runnable runnable) {
            return viewPropertyAnimator.withEndAction(runnable);
        }

        @DoNotInline
        static ViewPropertyAnimator withLayer(ViewPropertyAnimator viewPropertyAnimator) {
            return viewPropertyAnimator.withLayer();
        }

        @DoNotInline
        static ViewPropertyAnimator withStartAction(ViewPropertyAnimator viewPropertyAnimator,
                Runnable runnable) {
            return viewPropertyAnimator.withStartAction(runnable);
        }
    }

    @RequiresApi(18)
    static class Api18Impl {
        private Api18Impl() {
            // This class is not instantiable.
        }

        @DoNotInline
        static Interpolator getInterpolator(ViewPropertyAnimator viewPropertyAnimator) {
            return (Interpolator) viewPropertyAnimator.getInterpolator();
        }

    }

    @RequiresApi(21)
    static class Api21Impl {
        private Api21Impl() {
            // This class is not instantiable.
        }

        @DoNotInline
        static ViewPropertyAnimator translationZBy(ViewPropertyAnimator viewPropertyAnimator,
                float value) {
            return viewPropertyAnimator.translationZBy(value);
        }

        @DoNotInline
        static ViewPropertyAnimator translationZ(ViewPropertyAnimator viewPropertyAnimator,
                float value) {
            return viewPropertyAnimator.translationZ(value);
        }

        @DoNotInline
        static ViewPropertyAnimator z(ViewPropertyAnimator viewPropertyAnimator, float value) {
            return viewPropertyAnimator.z(value);
        }

        @DoNotInline
        static ViewPropertyAnimator zBy(ViewPropertyAnimator viewPropertyAnimator, float value) {
            return viewPropertyAnimator.zBy(value);
        }
    }

    @RequiresApi(19)
    static class Api19Impl {
        private Api19Impl() {
            // This class is not instantiable.
        }

        @DoNotInline
        static ViewPropertyAnimator setUpdateListener(ViewPropertyAnimator viewPropertyAnimator,
                ValueAnimator.AnimatorUpdateListener listener) {
            return viewPropertyAnimator.setUpdateListener(listener);
        }

    }
}