/** * Setup the Animator to achieve path morphing. * * @param anim The target Animator which will be updated. * @param arrayAnimator TypedArray for the ValueAnimator. * @return the PathDataEvaluator. */ private static TypeEvaluator setupAnimatorForPath(ValueAnimator anim, TypedArray arrayAnimator) { TypeEvaluator evaluator = null; String fromString = arrayAnimator.getString(R.styleable.Animator_vc_valueFrom); String toString = arrayAnimator.getString(R.styleable.Animator_vc_valueTo); PathParser.PathDataNode[] nodesFrom = PathParser.createNodesFromPathData(fromString); PathParser.PathDataNode[] nodesTo = PathParser.createNodesFromPathData(toString); if (nodesFrom != null) { if (nodesTo != null) { anim.setObjectValues(nodesFrom, nodesTo); if (!PathParser.canMorph(nodesFrom, nodesTo)) { throw new InflateException( arrayAnimator.getPositionDescription() + " Can't morph from " + fromString + " to " + toString); } } else { anim.setObjectValues((Object) nodesFrom); } evaluator = new PathDataEvaluator(PathParser.deepCopyNodes(nodesFrom)); } else if (nodesTo != null) { anim.setObjectValues((Object) nodesTo); evaluator = new PathDataEvaluator(PathParser.deepCopyNodes(nodesTo)); } if (DBG_ANIMATOR_INFLATER && evaluator != null) { Log.v(LOG_TAG, "create a new PathDataEvaluator here"); } return evaluator; }
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); } }); }