package com.kaichunlin.transition;
import android.app.Activity;
import android.support.annotation.CheckResult;
import android.support.annotation.FloatRange;
import android.support.annotation.IdRes;
import android.support.annotation.IntRange;
import android.support.annotation.NonNull;
import android.support.v7.widget.Toolbar;
import android.view.MenuItem;
import com.kaichunlin.transition.internal.TransitionControllerManager;
import com.nineoldandroids.animation.AnimatorSet;
import com.nineoldandroids.animation.ObjectAnimator;
/**
* Builder for {@link MenuItemTransition}.
*/
public class MenuItemTransitionBuilder extends AbstractTransitionBuilder<MenuItemTransitionBuilder, MenuItemTransition> implements MenuItemTransition.Setup {
/**
* Creates a transition effects builder for Toolbar {@link MenuItem}s.
*
* @param toolbar
* @return
*/
public static MenuItemTransitionBuilder transit(@NonNull Toolbar toolbar) {
return new MenuItemTransitionBuilder(toolbar);
}
/**
* Creates a builder for Toolbar {@link MenuItem}s.
*
* @param id Same as calling {@link Transition#setId(String)}, set an ID for debugging purpose.
* @param toolbar
* @return
*/
public static MenuItemTransitionBuilder transit(String id, @NonNull Toolbar toolbar) {
return new MenuItemTransitionBuilder(id, toolbar);
}
/**
* Creates a builder for a specific Toolbar {@link MenuItem}.
*
* @param menuId The ID of the MenuItem to have transition effect created.
* @param toolbar
* @return
*/
public static MenuItemTransitionBuilder transit(@IdRes int menuId, @NonNull Toolbar toolbar) {
return new MenuItemTransitionBuilder(menuId, toolbar);
}
/**
* Creates a builder for a specific Toolbar {@link MenuItem}.
*
* @param id Same as calling {@link Transition#setId(String)}, set an ID for debugging purpose.
* @param menuId The ID of the MenuItem to have transition effect created.
* @param toolbar
* @return
*/
public static MenuItemTransitionBuilder transit(String id, @IdRes int menuId, @NonNull Toolbar toolbar) {
return new MenuItemTransitionBuilder(id, menuId, toolbar);
}
private Toolbar mToolbar;
private int mMenuId;
private float mCascade;
private boolean mVisibleOnStartTransition;
private Activity mActivity;
private boolean mInvalidateOptionOnStopAnimation;
private MenuItemTransitionBuilder(@NonNull Toolbar toolbar) {
mToolbar = toolbar;
}
private MenuItemTransitionBuilder(String id, @NonNull Toolbar toolbar) {
mId = id;
mToolbar = toolbar;
}
private MenuItemTransitionBuilder(int menuId, @NonNull Toolbar toolbar) {
mMenuId = menuId;
mToolbar = toolbar;
}
private MenuItemTransitionBuilder(String id, int menuId, @NonNull Toolbar toolbar) {
mId = id;
mMenuId = menuId;
mToolbar = toolbar;
}
@Override
public MenuItemTransitionBuilder alpha(@FloatRange(from = 0.0, to = 1.0) float end) {
return alpha(1f, end);
}
@Override
public MenuItemTransitionBuilder rotation(float end) {
return rotation(0f, end);
}
@Override
public MenuItemTransitionBuilder rotationX(float end) {
return rotationX(0f, end);
}
@Override
public MenuItemTransitionBuilder rotationY(float end) {
return rotationY(0f, end);
}
@Override
public MenuItemTransitionBuilder scaleX(@FloatRange(from = 0.0) float end) {
return scaleX(0f, end);
}
@Override
public MenuItemTransitionBuilder scaleY(@FloatRange(from = 0.0) float end) {
return scaleY(0f, end);
}
@Override
public MenuItemTransitionBuilder scale(@FloatRange(from = 0.0) float end) {
return scale(0f, end);
}
@Override
public MenuItemTransitionBuilder translationX(float end) {
return translationX(0f, end);
}
@Override
public MenuItemTransitionBuilder translationY(float end) {
return translationY(0f, end);
}
@Override
public MenuItemTransitionBuilder x(float end) {
return x(0f, end);
}
@Override
public MenuItemTransitionBuilder y(float end) {
return y(0f, end);
}
/**
* Cascades the starting range of transition for each {@link android.view.MenuItem} such that the
* first {@link android.view.MenuItem} will transit from <i>start</i>, the 2nd MenuItem will
* transit from <i>start+cascade</i> and so on.
*
* @param cascade
* @return
*/
public MenuItemTransitionBuilder cascade(@FloatRange(from = 0.0) float cascade) {
mCascade = cascade;
return self();
}
/**
* See {@link MenuItemTransition#setVisibleOnStartAnimation(boolean)}.
*
* @param visible
* @return
*/
public MenuItemTransitionBuilder visibleOnStartAnimation(boolean visible) {
mVisibleOnStartTransition = visible;
return self();
}
/**
* See {@link MenuItemTransition#setInvalidateOptionOnStopTransition(Activity, boolean)}}.
*
* @param activity Activity that should have its invalidateOptionsMenu() method called, or null
* if invalidate parameter is false
* @param invalidate
* @return
*/
public MenuItemTransitionBuilder invalidateOptionOnStopTransition(@NonNull Activity activity, boolean invalidate) {
mActivity = activity;
mInvalidateOptionOnStopAnimation = invalidate;
return self();
}
@CheckResult
@Override
public MenuItemTransitionBuilder clone() {
MenuItemTransitionBuilder clone = (MenuItemTransitionBuilder) super.clone();
return clone;
}
@CheckResult(suggest = "The created MenuItemTransition should be utilized")
@Override
protected MenuItemTransition createTransition() {
MenuItemTransition transition = new MenuItemTransition(mId, mToolbar);
if (mMenuId != 0) {
transition.setMenuId(mMenuId);
}
//TODO clone() is required since the class implements ViewTransition.Setup and passes itself to ViewTransition, without clone ViewTransitions made from the same Builder will have their states intertwined
transition.setSetup(clone());
transition.setVisibleOnStartAnimation(mVisibleOnStartTransition);
if (mActivity != null) {
transition.setInvalidateOptionOnStopTransition(mActivity, mInvalidateOptionOnStopAnimation);
}
return transition;
}
@Override
protected MenuItemTransitionBuilder self() {
return this;
}
@Override
public void setupAnimation(@NonNull MenuItem mMenuItem, @NonNull TransitionControllerManager manager,
@IntRange(from = 0) int itemIndex, @IntRange(from = 0) int menuCount) {
if(mDelayed!=null) {
final int size = mDelayed.size();
for (int i = 0; i < size; i++) {
mDelayed.get(i).evaluate(manager.getTarget(), this);
}
}
ObjectAnimator anim = new ObjectAnimator();
anim.setValues(getValuesHolders());
AnimatorSet set = new AnimatorSet();
set.play(anim);
set.setStartDelay((long) (itemIndex * mCascade * SCALE_FACTOR));
set.setDuration((long) (SCALE_FACTOR - itemIndex * mCascade * SCALE_FACTOR));
manager.addAnimatorSetAsTransition(set).setRange(mStart, mEnd);
}
}