仿抖音短视频录制按钮动画

最近找工作,面试遇到了一个问题问抖音的那个录制按钮效果如何实现。说到这里熟悉自定义View的话,很容易就想到这里关键是考Xfermode的了解及使用。

话不多说先上图

 

项目源码

 现在就让我们来动手实现吧。这里控件的效果就要用到自定义VIew中重写OnDraw ()方法来实现了。

首先分析思路

1.这个动画初看的话也就是两个圆重叠,然后内部圆半径发生变化

2.重叠的圆石镂空的

3.xfermode可以解决图形重叠的绘制区域的问题

在这里先看一下xfermode经典的图形处理

在这里看到我们的外圆就是Dst,内圆就是src,我们要拿到的区域便是Dstout对应的区域,所以我们需要采用PorterDuff.Mode.DST_OUT模式

到这里思路已经很清晰了,下面就开始上代码

具体实现

  @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        //移动画布到控件中间
        canvas.translate(mViewWidth/2,mViewHeight/2);

        //这里没有对圆环大小做控制,只是为了测试效果,如果需要可以作为view属性
        //这是是个外圆半径200,内圆半径在150-190直接变化

        //动态计算内圆半径
        float offset = 150 + 40 * mAnimatorValue;

        //先画外圆
        mPaint.setColor(Color.RED);
        canvas.drawCircle(0,0,200,mPaint);

        //设置Xfermode为DST_OUT模式
        mPaint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.DST_OUT));

        //画内圆
        canvas.drawCircle(0,0,offset,mPaint);
        //重置Xfermode
        mPaint.setXfermode(null);

    }

 到这里已经跑起来就已经实现了这个动画效果,mAnimatorValue这个是通过属性动画来动态获取进度值,收缩动画通过修改内圆半径来实现。

注意事项

动画执行需要设置硬件加速或者软件加速,执行完需要关闭

 

  mStartAnimator.addListener(new AnimatorListenerAdapter() {
            @Override
            public void onAnimationStart(Animator animation) {
                super.onAnimationStart(animation);
                setLayerType(LAYER_TYPE_HARDWARE,null); setLayerType(LAYER_TYPE_HARDWARE,null); //这里也可以设置LAYER_TYPE_SOFTWARE,可以达到同样的效果
            }

            @Override
            public void onAnimationEnd(Animator animation) {
                super.onAnimationEnd(animation);
                setLayerType(LAYER_TYPE_NONE,null);
            }
        });

 

这里要注意的是如果执行动画不设置

setLayerType(LAYER_TYPE_HARDWARE,null);

那么就出现下面这样的效果

 

 本人菜鸟一枚,文章浅陋,有不当之处还望批评指正。

posted @ 2018-04-12 21:35  BlueSea017  阅读(2124)  评论(0编辑  收藏  举报