package com.kaichunlin.transition.animation; import android.view.View; import android.view.animation.LinearInterpolator; import android.view.animation.Transformation; import com.kaichunlin.transition.TransitionOperation; import java.lang.ref.WeakReference; import java.util.ArrayList; import java.util.List; /** * The default {@link StateController} used by {@link AnimationManager} and {@link TransitionAnimation} * to control animation state. */ class AnimationController extends android.view.animation.Animation implements StateController, android.view.animation.Animation.AnimationListener { private static final int STOP_END = 0x01; private static final int STOP_CANCEL = 0x02; private static final int STOP_RESET = 0x04; private final List<AbstractAnimation> mAnimationList = new ArrayList<>(); private WeakReference<View> mTargetRef; private boolean mReverse; private List<TransitionOperation> mTransitionList; private int mStopType; private boolean mEnded; AnimationController(View target, boolean reverse, final TransitionOperation transition) { this(target, reverse, new ArrayList<TransitionOperation>() {{ add(transition); }}); } AnimationController(View target, boolean reverse, List<TransitionOperation> transitionList) { mTargetRef = new WeakReference<>(target); mReverse = reverse; mTransitionList = transitionList; setAnimationListener(this); setInterpolator(new LinearInterpolator()); } @Override protected void applyTransformation(float interpolatedTime, Transformation t) { if (mStopType != 0) { return; } for (int i = 0; i < mTransitionList.size(); i++) { mTransitionList.get(i).updateProgress(mReverse ? 1 - interpolatedTime : interpolatedTime); } } @Override public void addAnimation(AbstractAnimation animation) { mAnimationList.add(animation); } @Override public void setAnimationDuration(long duration) { setDuration(duration); } @Override public void startController() { View target = mTargetRef.get(); if (target == null) { return; } mStopType = 0; mEnded = false; target.startAnimation(this); } /** * Currently not supported */ @Override public void pauseController() { //TODO currently does nothing } /** * Currently not supported */ @Override public void resumeController() { //TODO currently does nothing } @Override public void endController() { handleStop(STOP_END); AbstractAnimation ani; for (int i = 0, size = mAnimationList.size(); i < size; i++) { ani = mAnimationList.get(i); ani.getTransition().updateProgress(ani.isReverseAnimation() ? 0 : 1); } } @Override public void resetController() { handleStop(STOP_RESET); AbstractAnimation ani; for (int i = 0, size = mAnimationList.size(); i < size; i++) { ani = mAnimationList.get(i); ani.getTransition().updateProgress(ani.isReverseAnimation() ? 1 : 0); } } public void cancelController() { handleStop(STOP_CANCEL); } private void handleStop(int stopType) { this.mStopType = stopType; View target = mTargetRef.get(); if (target == null) { return; } target.clearAnimation(); } @Override public void onAnimationStart(android.view.animation.Animation animation) { for (int i = 0, size = mAnimationList.size(); i < size; i++) { mAnimationList.get(i).notifyAnimationStart(); } } @Override public void onAnimationEnd(android.view.animation.Animation animation) { if (mEnded) { return; } if (mStopType == 0) { mStopType = STOP_END; } AbstractAnimation ani; for (int i = 0, size = mAnimationList.size(); i < size; i++) { ani = mAnimationList.get(i); ani.setAnimating(false); switch (mStopType) { case STOP_END: ani.notifyAnimationEnd(); break; case STOP_CANCEL: ani.notifyAnimationCancel(); break; case STOP_RESET: ani.notifyAnimationReset(); break; } ani.getTransition().stopTransition(); } mEnded = true; } @Override public void onAnimationRepeat(android.view.animation.Animation animation) { } }