美文网首页
Android 自定义Loading动画

Android 自定义Loading动画

作者: 小白彡 | 来源:发表于2020-07-28 22:40 被阅读0次

    最近项目大改, 忙里偷闲 记录一下项目里用到的加载动画。。。。。
    开始了:
    UI大佬甩手扔过来一张GIF 说 : 我要这个效果。
    ........这 得加钱。。。
    好吧 先看看这张动图:


    o.gif

    既然活都接下了,只能硬着头皮上了。。
    对于这个稍微复杂一点的动画,当然得先拆分一下,分成简单的动画后逐一实现,
    看到这张动图,它一共包含三中动画效果
    1.整体旋转
    2.线条长短变化
    3.缩放

    既然已经拆分出来了,就可以一个一个实现了。。。

    1.线条长短变化
    这里我使用的是canvas.drawArc 绘制圆弧的方式实现的, 也可以用path的方式实现,
    这里圆弧分为两半,中间间距我设置为20,可以得到一个圆弧的弧度是160.
    添加属性动画, 让线条开始长短变化
    比较简单, 看一下代码:

     @Override
        protected void onDraw(Canvas canvas) {
            super.onDraw(canvas);
            arcRectF.set(paintStork, paintStork, getWidth() - paintStork, getHeight() - paintStork);
            //第一个圆弧
            canvas.drawArc(arcRectF, 270 + (intervalRadian >> 1), radian * progress, false, paint);
            //第二个圆弧
            canvas.drawArc(arcRectF, 90 + (intervalRadian >> 1), radian * progress, false, paint);
            if(!isStart){
                startAnim();
                isStart = true;
            }
        }
    
     private void startAnim(){
            valueAnimator = ValueAnimator.ofFloat(minRadian, 1f);
            valueAnimator.setDuration(rotatTime);
            valueAnimator.setRepeatMode(ValueAnimator.REVERSE);
            valueAnimator.setRepeatCount(ValueAnimator.INFINITE);
            valueAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
                @Override
                public void onAnimationUpdate(ValueAnimator animation) {
                    progress = (float) animation.getAnimatedValue();
                    postInvalidate();
                }
            });
            valueAnimator.start();
        }
    

    通过不断更新progress加上重绘,实现了圆弧的长短变化。

    2.旋转
    这部分如果用canvas实现的话 的不断更新圆弧的起始位置,相对于整个view的旋转来说复杂一点,
    所以我选择整个view的旋转, 为view添加一个普通的旋转动画

    看一下代码:

      private void startRotatWithScale() {
            // 利用 ObjectAnimator 实现旋转动画
            final AnimatorSet rotateAnimationSet = new AnimatorSet();
            rotationAnimator = ObjectAnimator.ofFloat(this, "rotation",0, 360);
            rotationAnimator.setDuration(rotatTime);
            rotationAnimator.setInterpolator(new LinearInterpolator());
            rotationAnimator.setRepeatCount(ValueAnimator.INFINITE);
            rotationAnimator.setRepeatMode(ValueAnimator.RESTART);
            rotateAnimationSet.playTogether(
                    rotationAnimator
            );
            rotateAnimationSet.start();
    

    现在就差一个缩放动画了。

    3.缩放动画
    这个缩放和普通的缩放不同,它每转三圈才缩放一次,这个不是很好控制,如果用计时器来就显得很冗余了,好在google给我们提供了关键帧动画, 通过关键帧动画, 可以控制缩放的时间段,这就很好弄了:
    看一下代码:

    Keyframe keyframe1 = Keyframe.ofFloat(0f, 1.0f);
            Keyframe keyframe2 = Keyframe.ofFloat(0.9f, 1.0f);
            Keyframe keyframe3 = Keyframe.ofFloat(1f, 0f);
            PropertyValuesHolder frameHodlerX = PropertyValuesHolder.ofKeyframe("scaleX",keyframe1,keyframe2,keyframe3);
    
            animatorX = ObjectAnimator.ofPropertyValuesHolder(this, frameHodlerX);
            animatorX.setDuration(scaleTime);
            animatorX.setRepeatCount(ValueAnimator.INFINITE);
            animatorX.setRepeatMode(ValueAnimator.REVERSE);
            animatorX.start();
    
            PropertyValuesHolder frameHodlerY = PropertyValuesHolder.ofKeyframe("scaleY",keyframe1,keyframe2,keyframe3);
    
            animatorY = ObjectAnimator.ofPropertyValuesHolder(this, frameHodlerY);
            animatorY.setDuration(scaleTime);
            animatorY.setRepeatCount(ValueAnimator.INFINITE);
            animatorY.setRepeatMode(ValueAnimator.REVERSE);
            animatorY.start();
    

    这样三个动画组合起来就实现了我想要的效果了:
    see see


    t.gif

    看上去还不错。。。。

    相关文章

      网友评论

          本文标题:Android 自定义Loading动画

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