Skip to content

Instantly share code, notes, and snippets.

@srcreigh
Last active August 29, 2015 14:06
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save srcreigh/fe5de9d3c05ea17ecbfd to your computer and use it in GitHub Desktop.
Save srcreigh/fe5de9d3c05ea17ecbfd to your computer and use it in GitHub Desktop.
package com.hackthenorth.android.util;
import android.animation.Animator;
import android.animation.TimeInterpolator;
import android.animation.ValueAnimator;
import android.annotation.SuppressLint;
import android.view.View;
/**
* "Because, honestly, why isn't android.animation.ViewPropertyAnimator an Animator in
* the first place?"
*
* Benefits of ViewPropertyAnimator being an Animator:
* - they're easily composed with android.animation.AnimatorSet
* - they're easily composed with android.animation.AnimatorSet
* - they're easily composed with android.animation.AnimatorSet
* - they're easily composed with android.animation.AnimatorSet
* - they're easily composed with android.animation.AnimatorSet
*
* You can use this class the same way as android.animation.ViewPropertyAnimator, except for a
* few things:
*
* 1. Rather than view.animate().foo(x).bar(y), you must construct the animator by doing new
* ViewPropertyAnimator(view).foo(x).bar(y).
*
* 2. The start() method is mandatory, rather than optional.
*
* 3. The setDuration, setStartDelay, and setInterpolator abstract Animator methods have
* equivalent methods setVPADuration, setVPAStartDelay, and setVPAInterpolator methods which
* return a reference to the ViewPropertyAnimator for chained method calls.
*/
public class ViewPropertyAnimator extends Animator {
private static final String TAG = "ViewPropertyAnimator";
/**
* This is the target view for the ViewPropertyAnimation. Note that the actual
* android.animation.ViewPropertyAnimation isn't created until the start() method is called.
*/
View mView;
// state constants
final long ALPHA_SET = 1;
final long ALPHA_BY_SET = 1 << 1;
final long ROTATION_SET = 1 << 2;
final long ROTATION_BY_SET = 1 << 3;
final long ROTATION_X_SET = 1 << 4;
final long ROTATION_X_BY_SET = 1 << 5;
final long ROTATION_Y_SET = 1 << 6;
final long ROTATION_Y_BY_SET = 1 << 7;
final long SCALE_X_SET = 1 << 8;
final long SCALE_X_BY_SET = 1 << 9;
final long SCALE_Y_SET = 1 << 10;
final long SCALE_Y_BY_SET = 1 << 11;
final long DURATION_SET = 1 << 12;
final long INTERPOLATOR_SET = 1 << 13;
final long LISTENER_SET = 1 << 14;
final long START_DELAY_SET = 1 << 15;
final long UPDATE_LISTENER_SET = 1 << 16;
final long TRANSLATION_X_SET = 1 << 17;
final long TRANSLATION_X_BY_SET = 1 << 18;
final long TRANSLATION_Y_SET = 1 << 19;
final long TRANSLATION_Y_BY_SET = 1 << 20;
final long END_ACTION_SET = 1 << 21;
final long WITH_LAYER_CALLED = 1 << 22;
final long START_ACTION_SET = 1 << 23;
final long X_SET = 1 << 24;
final long X_BY_SET = 1 << 25;
final long Y_SET = 1 << 26;
final long Y_BY_SET = 1 << 27;
long mState = 0;
// Mirror all the settings that you can pass to android.animation.ViewPropertyAnimator.
float mAlpha;
float mAlphaBy;
float mRotation;
float mRotationBy;
float mRotationX;
float mRotationXBy;
float mRotationY;
float mRotationYBy;
float mScaleX;
float mScaleXBy;
float mScaleY;
float mScaleYBy;
long mDuration;
TimeInterpolator mInterpolator;
AnimatorListener mListener;
long mStartDelay;
ValueAnimator.AnimatorUpdateListener mUpdateListener;
float mTranslationX;
float mTranslationXBy;
float mTranslationY;
float mTranslationYBy;
Runnable mEndAction;
Runnable mStartAction;
float mX;
float mXBy;
float mY;
float mYBy;
public ViewPropertyAnimator(View view) {
mView = view;
}
// Animator methods
@Override
public long getStartDelay() {
return mStartDelay;
}
@Override
public void setStartDelay(long startDelay) {
mState |= START_DELAY_SET;
mStartDelay = startDelay;
}
@Override
public Animator setDuration(long duration) {
mState |= DURATION_SET;
mDuration = duration;
return this;
}
@Override
public long getDuration() {
return mDuration;
}
@Override
public void setInterpolator(TimeInterpolator value) {
mState |= INTERPOLATOR_SET;
mInterpolator = value;
}
/**
* Unsupported
* @return false
*/
@Deprecated
@Override
public boolean isRunning() { return false; }
@SuppressLint("NewApi")
@Override
public void start() {
android.view.ViewPropertyAnimator anim = mView.animate();
if ((mState & ALPHA_SET) != 0) anim.alpha(mAlpha);
if ((mState & ALPHA_BY_SET) != 0) anim.alphaBy(mAlphaBy);
if ((mState & ROTATION_SET) != 0) anim.rotation(mRotation);
if ((mState & ROTATION_BY_SET) != 0) anim.rotationBy(mRotationBy);
if ((mState & ROTATION_X_SET) != 0) anim.rotationX(mRotationX);
if ((mState & ROTATION_X_BY_SET) != 0) anim.rotationXBy(mRotationXBy);
if ((mState & ROTATION_Y_SET) != 0) anim.rotationY(mRotationY);
if ((mState & ROTATION_Y_BY_SET) != 0) anim.rotationYBy(mRotationYBy);
if ((mState & SCALE_X_SET) != 0) anim.scaleX(mScaleX);
if ((mState & SCALE_X_BY_SET) != 0) anim.scaleXBy(mScaleXBy);
if ((mState & SCALE_Y_SET) != 0) anim.scaleY(mScaleY);
if ((mState & SCALE_Y_BY_SET) != 0) anim.scaleYBy(mScaleYBy);
if ((mState & DURATION_SET) != 0) anim.setDuration(mDuration);
if ((mState & INTERPOLATOR_SET) != 0) anim.setInterpolator(mInterpolator);
if ((mState & LISTENER_SET) != 0) anim.setListener(mListener);
if ((mState & START_DELAY_SET) != 0) anim.setStartDelay(mStartDelay);
if ((mState & UPDATE_LISTENER_SET) != 0) anim.setUpdateListener(mUpdateListener);
if ((mState & TRANSLATION_X_SET) != 0) anim.translationX(mTranslationX);
if ((mState & TRANSLATION_X_BY_SET) != 0) anim.translationXBy(mTranslationXBy);
if ((mState & TRANSLATION_Y_SET) != 0) anim.translationY(mTranslationY);
if ((mState & TRANSLATION_Y_BY_SET) != 0) anim.translationYBy(mTranslationYBy);
if ((mState & END_ACTION_SET) != 0) anim.withEndAction(mEndAction);
if ((mState & WITH_LAYER_CALLED) != 0) anim.withLayer();
if ((mState & START_ACTION_SET) != 0) anim.withStartAction(mStartAction);
if ((mState & X_SET) != 0) anim.x(mX);
if ((mState & X_BY_SET) != 0) anim.xBy(mXBy);
if ((mState & Y_SET) != 0) anim.y(mY);
if ((mState & Y_BY_SET) != 0) anim.yBy(mYBy);
anim.start();
}
// ViewPropertyAnimator cloned methods
public ViewPropertyAnimator alpha(float value) {
mState |= ALPHA_SET;
mAlpha = value;
return this;
}
public ViewPropertyAnimator alphaBy(float value) {
mState |= ALPHA_BY_SET;
mAlphaBy = value;
return this;
}
public ViewPropertyAnimator rotation(float value) {
mState |= ROTATION_SET;
mRotation = value;
return this;
}
public ViewPropertyAnimator rotationBy(float value) {
mState |= ROTATION_BY_SET;
mRotation = value;
return this;
}
public ViewPropertyAnimator rotationX(float value) {
mState |= ROTATION_X_SET;
mRotationX = value;
return this;
}
public ViewPropertyAnimator rotationXBy(float value) {
mState |= ROTATION_X_BY_SET;
mRotationXBy = value;
return this;
}
public ViewPropertyAnimator rotationY(float value) {
mState |= ROTATION_Y_SET;
mRotationY = value;
return this;
}
public ViewPropertyAnimator rotationYBy(float value) {
mState |= ROTATION_Y_BY_SET;
mRotationYBy = value;
return this;
}
public ViewPropertyAnimator scaleX(float value) {
mState |= SCALE_X_SET;
mScaleX = value;
return this;
}
public ViewPropertyAnimator scaleXBy(float value) {
mState |= SCALE_X_BY_SET;
mScaleXBy = value;
return this;
}
public ViewPropertyAnimator scaleY(float value) {
mState |= SCALE_Y_SET;
mScaleY = value;
return this;
}
public ViewPropertyAnimator scaleYBy(float value) {
mState |= SCALE_Y_BY_SET;
mScaleYBy = value;
return this;
}
// these methods can't be mirrored exactly, as they conflict with the abstract methods from
// Animator that we have to implement. so an appropriate substitute method name is given.
public ViewPropertyAnimator setVPADuration(long duration) {
mState |= DURATION_SET;
mDuration = duration;
return this;
}
public ViewPropertyAnimator setVPAInterpolator(TimeInterpolator interpolator) {
mState |= INTERPOLATOR_SET;
mInterpolator = interpolator;
return this;
}
public ViewPropertyAnimator setListener(AnimatorListener listener) {
mState |= LISTENER_SET;
mListener = listener;
return this;
}
// same as with setVPADuration
public ViewPropertyAnimator setVPAStartDelay(long startDelay) {
mState |= START_DELAY_SET;
mStartDelay = startDelay;
return this;
}
public ViewPropertyAnimator setUpdateListener(ValueAnimator.AnimatorUpdateListener listener) {
mState |= UPDATE_LISTENER_SET;
mUpdateListener = listener;
return this;
}
public ViewPropertyAnimator translationX(float value) {
mState |= TRANSLATION_X_SET;
mTranslationX = value;
return this;
}
public ViewPropertyAnimator translationXBy(float value) {
mState |= TRANSLATION_X_BY_SET;
mTranslationXBy = value;
return this;
}
public ViewPropertyAnimator translationY(float value) {
mState |= TRANSLATION_Y_SET;
mTranslationY = value;
return this;
}
public ViewPropertyAnimator translationYBy(float value) {
mState |= TRANSLATION_Y_BY_SET;
mTranslationYBy = value;
return this;
}
public ViewPropertyAnimator withEndAction(Runnable runnable) {
mState |= END_ACTION_SET;
mEndAction = runnable;
return this;
}
public ViewPropertyAnimator withStartAction(Runnable runnable) {
mState |= START_ACTION_SET;
mStartAction = runnable;
return this;
}
public ViewPropertyAnimator x(float value) {
mState |= X_SET;
mX = value;
return this;
}
public ViewPropertyAnimator xBy(float value) {
mState |= X_BY_SET;
mXBy = value;
return this;
}
public ViewPropertyAnimator y(float value) {
mState |= Y_SET;
mY = value;
return this;
}
public ViewPropertyAnimator yBy(float value) {
mState |= Y_BY_SET;
mYBy = value;
return this;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment