仿雅虎视频加载动画

今天无意间看到雅虎视频里面的加载动画挺有趣的。效果如下:
这里写图片描述
就尝试自己用自定义view简单的实现一下,效果图如下:
这里写图片描述
其实主要就是两个圆弧的变化加上一个旋转动画。
首先定义一个自定义view类 YahooloadingView。定义出需要使用到的参数:

    private Paint paint;

    private RectF rectF;

    private int width = 360;

    private int progress = 0;

    private int status = 1;


    private int startOne = 0;
    private int startTwo = 180;

    private int endOne = progress;
    private int endTwo = progress;

这里为了方便,我们将view的直径写死为固定360,定义出两段圆弧的初始位置和弧度。
然后进行测量:

 @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        setMeasuredDimension(width, width);
    }

最后进行绘制:

 @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);

        paintLoadview(canvas);

    }
    private void paintLoadview(Canvas canvas) {

        canvas.drawArc(rectF, startOne, endOne, false, paint);

        canvas.drawArc(rectF, startTwo, endTwo, false, paint);

    }

简单的几行代码后,我们得到了两段圆弧。那么怎样让它动起来呢?
核心逻辑:
第一,使用handler来更改数据达到更新ui的目的。
第二,观察原动画的圆弧变化规律,发现圆弧有两个阶段,一阶段为正常伸长,另一阶段为反向缩短。因此我们使用status来区分与圆弧的两个阶段。正常伸长时,初始位置不变,弧度变长;反向缩短时,弧度变短,圆弧末端不变,初始位置随弧度变化。
第三,创建旋转动画 rotateAnimation,让view旋转起来。

第一二步:

private Handler handler = new Handler(new Handler.Callback() {
        @Override
        public boolean handleMessage(Message msg) {

            if (progress >= 180) {
                status = -1;
            }
            if (progress <= 0) {
                status = 3;
            }
            progress += status;

            endOne = progress;
            endTwo = progress;


            if (status == -1) {
                startOne = 180 - progress;
            }
            if (startOne >= 180) {
                startOne = 0;
            }

            if (status == -1) {
                startTwo = 360 - progress;
            }
            if (startTwo >= 360) {
                startTwo = 180;
            }

            invalidate();

            return true;
        }
    });

第三步:

 private void initAnimation() {
        RotateAnimation rotateAnimation = new RotateAnimation(0, 360, Animation.RELATIVE_TO_SELF, 0.5f, Animation.RELATIVE_TO_SELF, 0.5f);
        rotateAnimation.setDuration(12000);   //设置动画播放时长
        rotateAnimation.setRepeatCount(Animation.INFINITE); //设置动画循环播放
        rotateAnimation.setInterpolator(new LinearInterpolator());  //设置动画以均匀的速率在改变
        this.startAnimation(rotateAnimation);

    }

这样就实现了循环更新ui的功能了,整个view的代码就差不多了,因为代码不是很多,就把源码全部贴出来吧。

package com.benhuan.myyahooloadingviewdemo;

import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.RectF;
import android.os.Handler;
import android.os.Message;
import android.os.SystemClock;
import android.util.AttributeSet;
import android.view.View;
import android.view.animation.AccelerateDecelerateInterpolator;
import android.view.animation.Animation;
import android.view.animation.AnticipateInterpolator;
import android.view.animation.CycleInterpolator;
import android.view.animation.Interpolator;
import android.view.animation.LinearInterpolator;
import android.view.animation.RotateAnimation;

/**
 * Created by xieminfeng on 2016/11/9.
 */
public class Yahooloadingview extends View {

    private Paint paint;

    private RectF rectF;

    private int width = 360;

    private int progress = 0;

    private int status = 1;


    private int startOne = 0;
    private int startTwo = 180;

    private int endOne = progress;
    private int endTwo = progress;


    private Handler handler = new Handler(new Handler.Callback() {
        @Override
        public boolean handleMessage(Message msg) {

            if (progress >= 180) {
                status = -1;
            }
            if (progress <= 0) {
                status = 3;
            }
            progress += status;

            endOne = progress;
            endTwo = progress;


            if (status == -1) {
                startOne = 180 - progress;
            }
            if (startOne >= 180) {
                startOne = 0;
            }

            if (status == -1) {
                startTwo = 360 - progress;
            }
            if (startTwo >= 360) {
                startTwo = 180;
            }

            invalidate();

            return true;
        }
    });


    public Yahooloadingview(Context context) {
        this(context, null);
    }

    public Yahooloadingview(Context context, AttributeSet attrs) {
        this(context, attrs, 0);
    }

    public Yahooloadingview(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        initPaint();
        initRectF();
        initThread();
        initAnimation();
    }

    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        setMeasuredDimension(width, width);
    }

    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);

        paintLoadview(canvas);

    }
    private void paintLoadview(Canvas canvas) {

        canvas.drawArc(rectF, startOne, endOne, false, paint);

        canvas.drawArc(rectF, startTwo, endTwo, false, paint);

    }

    private void initPaint() {
        paint = new Paint();
        paint.setColor(Color.RED);
        paint.setAntiAlias(true);
        paint.setStrokeWidth(30);
        paint.setDither(true);
        paint.setStyle(Paint.Style.STROKE);
    }


    private void initRectF() {
        rectF = new RectF(30, 30, width - 30, width - 30);
    }




    private void initThread() {
        new Thread(new Runnable() {
            @Override
            public void run() {
                while (true) {
                    handler.sendEmptyMessageDelayed(0, 1000);
                    SystemClock.sleep(8);
                }
            }
        }).start();
    }

    private void initAnimation() {
        RotateAnimation rotateAnimation = new RotateAnimation(0, 360, Animation.RELATIVE_TO_SELF, 0.5f, Animation.RELATIVE_TO_SELF, 0.5f);
        rotateAnimation.setDuration(12000);   //设置动画播放时长
        rotateAnimation.setRepeatCount(Animation.INFINITE); //设置动画循环播放
        rotateAnimation.setInterpolator(new LinearInterpolator());  //设置动画以均匀的速率在改变
        this.startAnimation(rotateAnimation);

    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值