package com.marshalchen.common.uimodule.easyandroidanimations;
import android.animation.Animator;
import android.animation.AnimatorListenerAdapter;
import android.animation.AnimatorSet;
import android.animation.ObjectAnimator;
import android.animation.TimeInterpolator;
import android.view.View;
import android.view.ViewGroup;
import android.view.animation.AccelerateDecelerateInterpolator;
/**
* This animation rotates the view by a customizable number of degrees and at a
* customizable pivot point.
*
* @author SiYao
*
*/
public class RotationAnimation extends Animation implements Combinable {
public static final int PIVOT_CENTER = 0, PIVOT_TOP_LEFT = 1,
PIVOT_TOP_RIGHT = 2, PIVOT_BOTTOM_LEFT = 3, PIVOT_BOTTOM_RIGHT = 4;
float degrees;
int pivot;
TimeInterpolator interpolator;
long duration;
AnimationListener listener;
/**
* This animation rotates the view by a customizable number of degrees and
* at a customizable pivot point.
*
* @param view
* The view to be animated.
*/
public RotationAnimation(View view) {
this.view = view;
degrees = 360;
pivot = PIVOT_CENTER;
interpolator = new AccelerateDecelerateInterpolator();
duration = DURATION_LONG;
listener = null;
}
@Override
public void animate() {
getAnimatorSet().start();
}
@Override
public AnimatorSet getAnimatorSet() {
ViewGroup parentView = (ViewGroup) view.getParent(), rootView = (ViewGroup) view
.getRootView();
while (parentView != rootView) {
parentView.setClipChildren(false);
parentView = (ViewGroup) parentView.getParent();
}
rootView.setClipChildren(false);
float pivotX, pivotY, viewWidth = view.getWidth(), viewHeight = view
.getHeight();
switch (pivot) {
case PIVOT_TOP_LEFT:
pivotX = 1f;
pivotY = 1f;
break;
case PIVOT_TOP_RIGHT:
pivotX = viewWidth;
pivotY = 1f;
break;
case PIVOT_BOTTOM_LEFT:
pivotX = 1f;
pivotY = viewHeight;
break;
case PIVOT_BOTTOM_RIGHT:
pivotX = viewWidth;
pivotY = viewHeight;
break;
default:
pivotX = viewWidth / 2;
pivotY = viewHeight / 2;
break;
}
view.setPivotX(pivotX);
view.setPivotY(pivotY);
AnimatorSet rotationSet = new AnimatorSet();
rotationSet.play(ObjectAnimator.ofFloat(view, View.ROTATION,
view.getRotation() + degrees));
rotationSet.setInterpolator(interpolator);
rotationSet.setDuration(duration);
rotationSet.addListener(new AnimatorListenerAdapter() {
@Override
public void onAnimationEnd(Animator animation) {
if (getListener() != null) {
getListener().onAnimationEnd(RotationAnimation.this);
}
}
});
return rotationSet;
}
/**
* @return The number of degrees to rotate by.
*/
public float getDegrees() {
return degrees;
}
/**
* In order to rotate anti-clockwise, the number of degrees should be
* negative.
*
* @param degrees
* The number of degrees to set to rotate by.
* @return This object, allowing calls to methods in this class to be
* chained.
*/
public RotationAnimation setDegrees(float degrees) {
this.degrees = degrees;
return this;
}
/**
* The available pivot points are <code>PIVOT_CENTER</code>,
* <code>PIVOT_TOP_LEFT</code>, <code>PIVOT_TOP_RIGHT</code>,
* <code>PIVOT_BOTTOM_LEFT</code> and <code>PIVOT_BOTTOM_RIGHT</code>.
*
* @return The pivot point for rotation.
*/
public int getPivot() {
return pivot;
}
/**
* The available pivot points are <code>PIVOT_CENTER</code>,
* <code>PIVOT_TOP_LEFT</code>, <code>PIVOT_TOP_RIGHT</code>,
* <code>PIVOT_BOTTOM_LEFT</code> and <code>PIVOT_BOTTOM_RIGHT</code>.
*
* @param pivot
* The pivot point to set for rotation.
* @return This object, allowing calls to methods in this class to be
* chained.
*/
public RotationAnimation setPivot(int pivot) {
this.pivot = pivot;
return this;
}
/**
* @return The interpolator of the entire animation.
*/
public TimeInterpolator getInterpolator() {
return interpolator;
}
/**
* @param interpolator
* The interpolator of the entire animation to set.
*/
public RotationAnimation setInterpolator(TimeInterpolator interpolator) {
this.interpolator = interpolator;
return this;
}
/**
* @return The duration of the entire animation.
*/
public long getDuration() {
return duration;
}
/**
* @param duration
* The duration of the entire animation to set.
* @return This object, allowing calls to methods in this class to be
* chained.
*/
public RotationAnimation setDuration(long duration) {
this.duration = duration;
return this;
}
/**
* @return The listener for the end of the animation.
*/
public AnimationListener getListener() {
return listener;
}
/**
* @param listener
* The listener to set for the end of the animation.
* @return This object, allowing calls to methods in this class to be
* chained.
*/
public RotationAnimation setListener(AnimationListener listener) {
this.listener = listener;
return this;
}
}