手记

自己做一个Android圆形揭示动画

圆形揭示动画在很多情况下都可以使用,比如说转场、打开popupwidow和覆盖一层新的view。
官方也提供了一个类专门提供这个动画的封装:

ViewAnimationUtils.createCircularReveal(View view,            int centerX,  int centerY, float startRadius, float endRadius)

然而这个方法必须api 5.0以上才能使用,既然如此不如自己动手造轮子。

思路:
1.只负责显示的范围,所以继承自FrameLayout,具体显示的内容由Child负责。
2.如何控制child显示的区域?在dispatchDraw中调用canvas.clipPath(Path path)把需要显示的区域裁剪出来。
3.如何显示圆?

 mCirclePath.reset();
 mCirclePath.addCircle(float x, float y, float radius, Direction dir)

4.动画用ValueAnimator。

具体流程:

 /**
     * 开始揭示动画
     * @param x 动画开始位置的x值
     * @param y 动画开始位置的y值
     */
    public void revealLayout(int x, int y){
        mCenterX = x;
        mCenterY = y;
        computeFarthest();
        computeVisibleRegion();        if (mAnimator == null) {
            mAnimator = ValueAnimator.ofFloat(0,1);
            mAnimator.setDuration(DEFAULT_ANIMATION_DURATION);
            mAnimator.setInterpolator(new DecelerateInterpolator());
            mAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {                @Override
                public void onAnimationUpdate(ValueAnimator animation) {
                    mAnimationValue = (float) animation.getAnimatedValue();
                    postInvalidate((int) (mVisibleRectF.left*mAnimationValue),(int) (mVisibleRectF.top*mAnimationValue)
                            ,(int) (mVisibleRectF.right*mAnimationValue),(int) (mVisibleRectF.bottom*mAnimationValue));

                }
            });
        }
        mAnimator.start();
    }

开始动画,传入动画开始的坐标值xy。
computeFarthest()计算动画开始点与Layout四个角的最远距离,即圆形为最大时的半径。
computeVisibleRegion()计算圆形显示区域的外界矩形,用于postInvalidate()时指定刷新的区域,减少绘制开销。

  @Override
    protected void dispatchDraw(Canvas canvas) {        if (mAnimationValue == 0){            return;
        }
        canvas.save();
        mCirclePath.reset();
        mCirclePath.addCircle(mCenterX,mCenterY,mFarthest*mAnimationValue, Path.Direction.CW);
        canvas.clipPath(mCirclePath);        super.dispatchDraw(canvas);
        canvas.restore();
    }

动画开始前不绘制Layout里的内容,动画开始后根据mAnimationValue的值改变圆形的大小。mFarthest为之前通过computeFarthest()计算出来的结果。

原文链接:http://www.apkbus.com/blog-822715-77235.html

0人推荐
随时随地看视频
慕课网APP