美文网首页
Android使用Canvas实现带加载动画的Button

Android使用Canvas实现带加载动画的Button

作者: 奋斗小青年Jerome | 来源:发表于2017-12-04 17:53 被阅读862次

    这个笔记是为了巩固之前的Canvas知识
    先看一下效果图


    loading.gif

    其实效果看上去很简单,原理也简单,分析一下:

    1. 使用Canvas画一个普通按钮,并在点击之后从矩形逐渐先缩放成两个半圆加上中间的矩形;
    2. 从两个半圆和中间矩形组成的形状,再次渐变成最终的圆,最后在圆上绘制转动的圆圈;

    现在分析一下代码怎么写:

    1. Canvas绘制带圆角的矩形,需要使用
      public void drawRoundRect(@NonNull RectF rect, float rx, float ry, @NonNull Paint paint) {
            super.drawRoundRect(rect, rx, ry, paint);
        }
    

    其中的参数rx指x方向上的圆角半径,ry指y方向上的圆角半径
    只需要在一段时间内,让这个圆角半径等于高度的1/2,就是半圆了


    image.png

    ValueAnimator的addUpdateListener可以监听在一段时间内,某个元素从开始到结束的变化,并返回这个变化的因子,这个circleAngle 就是圆角的变化因子,它从0(我这里默认不绘制带圆角),变化到view高度的1/2

    
        /**
         * 设置矩形过度到圆角矩形的动画
         */
        private void startRoundCircleAnimation() {
            animatorRectToRound = ValueAnimator.ofInt(0, mHeight / 2);
            animatorRectToRound.setDuration(circleDuration);
            animatorRectToRound.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
                @Override
                public void onAnimationUpdate(ValueAnimator animation) {
                    circleAngle = (int) animation.getAnimatedValue();
                    invalidate();
                }
            });
        }
    
    1. 从圆角圆角矩形到圆的变换,先看图


      image.png

      这一段就是整个View的起始宽度,最终变换成一个圆,那么中间这一段就是要压缩掉的,两个半圆合成一个圆

     /**
         * 设置圆角矩形过度到圆的动画
         */
        private void startRectRoundAnimation() {
            animatorRoundToCircle = ValueAnimator.ofInt(0, defaultDistance);
            animatorRoundToCircle.setDuration(duration);
            animatorRoundToCircle.addListener(new Animator.AnimatorListener() {
                @Override
                public void onAnimationStart(Animator animation) {
    
                }
    
                @Override
                public void onAnimationEnd(Animator animation) {
                    //矩形完全变成圆之后,再绘制loading圆圈
                    startDrawLoad = true;
                    disableClick = true;
                }
    
                @Override
                public void onAnimationCancel(Animator animation) {
    
                }
    
                @Override
                public void onAnimationRepeat(Animator animation) {
    
                }
            });
            animatorRoundToCircle.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
                @Override
                public void onAnimationUpdate(ValueAnimator animation) {
                    circleDistance = (int) animation.getAnimatedValue();
                    int alpha = 255 - (circleDistance * 255) / defaultDistance;
                    textPaint.setAlpha(alpha);
                    invalidate();
                }
            });
        }
    

    这里代码直接是从圆角矩形压缩到了圆,没有做分开压缩;并且压缩过程中将字体也从不透明变到透明

    1. 绘制中间的圆圈,并旋转
      /***
         * 绘制加载圆圈
         * @param canvas
         */
        private void drawLoad(Canvas canvas) {
            canvas.translate(mWidth / 2, mHeight / 2);
            canvas.rotate(degree);
            float r = mHeight / 3;
            RectF rectf = new RectF(-r, -r, r, r);
            canvas.drawArc(rectf, 0, loadingAnge, false, loadPaint);
        }
    

    旋转的原理:
    循环的旋转画布,其实真正画的那个圆圈没有旋转,只是将后面的Canvas旋转了
    drawArc就多说了,使用一个RectF来绘制扇形,扇形的最外边距就是这个矩形的外切线
    注意:
    注意旋转画布之前,需要将画布移动,再旋转画布才能生效
    关于旋转画布
    黄色部分是屏幕,蓝色部分为画布,红色为真正画的内容

    canvas.translate(200, 100);
    
    image.png

    **注意:

    1. 旋转是针对于x和y坐标的(0,0)点的,x和y轴是会旋转的,
      还有一个旋转方法是canvas.rotate(90,x,y);就是绕x,y点旋转
    2. 图片永远显示在canvas中的,图片相对于canvas是没有任何变化的**
    canvas.rotate(90);
    
    image.png

    参考了大神的一些讲Canvas的博客

    相关文章

      网友评论

          本文标题:Android使用Canvas实现带加载动画的Button

          本文链接:https://www.haomeiwen.com/subject/chbxixtx.html