/* * Copyright 2014 Oguz Bilgener */ package com.marshalchen.common.uimodule.circularfloatingactionmenu.animation; import android.animation.Animator; import android.animation.ObjectAnimator; import android.animation.PropertyValuesHolder; import android.graphics.Point; import android.view.View; import android.view.animation.AccelerateDecelerateInterpolator; import android.view.animation.OvershootInterpolator; import com.marshalchen.common.uimodule.circularfloatingactionmenu.FloatingActionMenu; /** * An example animation handler * Animates translation, rotation, scale and alpha at the same time using Property Animation APIs. */ public class DefaultAnimationHandler extends MenuAnimationHandler { /** duration of animations, in milliseconds */ protected static final int DURATION = 500; /** duration to wait between each of */ protected static final int LAG_BETWEEN_ITEMS = 20; /** holds the current state of animation */ private boolean animating; public DefaultAnimationHandler() { setAnimating(false); } @Override public void animateMenuOpening(Point center) { super.animateMenuOpening(center); setAnimating(true); Animator lastAnimation = null; for (int i = 0; i < menu.getSubActionItems().size(); i++) { menu.getSubActionItems().get(i).view.setScaleX(0); menu.getSubActionItems().get(i).view.setScaleY(0); menu.getSubActionItems().get(i).view.setAlpha(0); PropertyValuesHolder pvhX = PropertyValuesHolder.ofFloat(View.TRANSLATION_X, menu.getSubActionItems().get(i).x - center.x + menu.getSubActionItems().get(i).width / 2); PropertyValuesHolder pvhY = PropertyValuesHolder.ofFloat(View.TRANSLATION_Y, menu.getSubActionItems().get(i).y - center.y + menu.getSubActionItems().get(i).height / 2); PropertyValuesHolder pvhR = PropertyValuesHolder.ofFloat(View.ROTATION, 720); PropertyValuesHolder pvhsX = PropertyValuesHolder.ofFloat(View.SCALE_X, 1); PropertyValuesHolder pvhsY = PropertyValuesHolder.ofFloat(View.SCALE_Y, 1); PropertyValuesHolder pvhA = PropertyValuesHolder.ofFloat(View.ALPHA, 1); final ObjectAnimator animation = ObjectAnimator.ofPropertyValuesHolder(menu.getSubActionItems().get(i).view, pvhX, pvhY, pvhR, pvhsX, pvhsY, pvhA); animation.setDuration(DURATION); animation.setInterpolator(new OvershootInterpolator(0.9f)); animation.addListener(new SubActionItemAnimationListener(menu.getSubActionItems().get(i), ActionType.OPENING)); if(i == 0) { lastAnimation = animation; } // Put a slight lag between each of the menu items to make it asymmetric animation.setStartDelay((menu.getSubActionItems().size() - i) * LAG_BETWEEN_ITEMS); animation.start(); } if(lastAnimation != null) { lastAnimation.addListener(new LastAnimationListener()); } } @Override public void animateMenuClosing(Point center) { super.animateMenuOpening(center); setAnimating(true); Animator lastAnimation = null; for (int i = 0; i < menu.getSubActionItems().size(); i++) { PropertyValuesHolder pvhX = PropertyValuesHolder.ofFloat(View.TRANSLATION_X, - (menu.getSubActionItems().get(i).x - center.x + menu.getSubActionItems().get(i).width / 2)); PropertyValuesHolder pvhY = PropertyValuesHolder.ofFloat(View.TRANSLATION_Y, - (menu.getSubActionItems().get(i).y - center.y + menu.getSubActionItems().get(i).height / 2)); PropertyValuesHolder pvhR = PropertyValuesHolder.ofFloat(View.ROTATION, -720); PropertyValuesHolder pvhsX = PropertyValuesHolder.ofFloat(View.SCALE_X, 0); PropertyValuesHolder pvhsY = PropertyValuesHolder.ofFloat(View.SCALE_Y, 0); PropertyValuesHolder pvhA = PropertyValuesHolder.ofFloat(View.ALPHA, 0); final ObjectAnimator animation = ObjectAnimator.ofPropertyValuesHolder(menu.getSubActionItems().get(i).view, pvhX, pvhY, pvhR, pvhsX, pvhsY, pvhA); animation.setDuration(DURATION); animation.setInterpolator(new AccelerateDecelerateInterpolator()); animation.addListener(new SubActionItemAnimationListener(menu.getSubActionItems().get(i), ActionType.CLOSING)); if(i == 0) { lastAnimation = animation; } animation.setStartDelay((menu.getSubActionItems().size() - i) * LAG_BETWEEN_ITEMS); animation.start(); } if(lastAnimation != null) { lastAnimation.addListener(new LastAnimationListener()); } } @Override public boolean isAnimating() { return animating; } @Override protected void setAnimating(boolean animating) { this.animating = animating; } protected class SubActionItemAnimationListener implements Animator.AnimatorListener { private FloatingActionMenu.Item subActionItem; private ActionType actionType; public SubActionItemAnimationListener(FloatingActionMenu.Item subActionItem, ActionType actionType) { this.subActionItem = subActionItem; this.actionType = actionType; } @Override public void onAnimationStart(Animator animation) { } @Override public void onAnimationEnd(Animator animation) { restoreSubActionViewAfterAnimation(subActionItem, actionType); } @Override public void onAnimationCancel(Animator animation) { restoreSubActionViewAfterAnimation(subActionItem, actionType); } @Override public void onAnimationRepeat(Animator animation) {} } }