private void startSendingAnimation(final RevealView.RevealAnimationListener listener) { final int width = mFab.getLeft(); final int height = mFab.getTop(); ValueAnimator valueAnimator = new ValueAnimator(); valueAnimator.setDuration(Const.DURATION / 2); valueAnimator.setObjectValues(new PointF(0, 0)); valueAnimator.setInterpolator(new DecelerateInterpolator()); valueAnimator.setEvaluator( new TypeEvaluator<PointF>() { @Override public PointF evaluate(float fraction, PointF startValue, PointF endValue) { PointF point = new PointF(); point.x = (width) * (1 - fraction / 2); point.y = (height) - 0.85f * (height) * (fraction / 2) * (fraction / 2); return point; } }); valueAnimator.start(); valueAnimator.addUpdateListener( new ValueAnimator.AnimatorUpdateListener() { @Override public void onAnimationUpdate(ValueAnimator animation) { PointF point = (PointF) animation.getAnimatedValue(); mFab.setX(point.x); mFab.setY(point.y); } }); valueAnimator.addListener( new AnimatorListenerAdapter() { @Override public void onAnimationEnd(Animator animation) { super.onAnimationEnd(animation); mRevealView.reveal( (int) mFab.getX() + mFab.getWidth() / 2, (int) mFab.getY() + mFab.getHeight() / 2, getThemeColor(), Const.RADIUS, Const.DURATION, listener); } }); }