类似UC浏览器三个圆点加载控件

在UC浏览器上,我们能够看到这样效果的加载控件,三个圆点同时滑动更换位置,这篇文章将会讲解如何实现这种效果
这里写图片描述

分析点的运动轨迹

根据效果我们可以看出三个点的轨迹都不相同,现在我们来逐一进行分析

第一个点运动轨迹

第一个点的运动轨迹是从初始位置向上运动,达到最高点后向下运动穿过第二个点的初始位置后继续向下运动,达到最低点后重新向上运动,最终抵达第三个点的初始位置,整个过程中,第一个点一直向右平行移动,并且颜色逐渐变浅

第二个点运动轨迹

第二个点的运动轨迹是从初始位置向下运动,达到最低点后向上运动,最终抵达第一个点的初始位置,整个过程中,第二个点一直向左平行移动,且颜色逐渐加深

第三个点的运动轨迹
第三个点的运动轨迹是从初始位置向上运动,达到最高点后向下运动,最终抵达第二个点的初始位置,整个过程中,第三个点一直向左平行移动,且颜色逐渐加深

三个点在整个运动过程中所花费的时间是相同的,也就是说,第一个点从初始位置运动到第三个点的初始位置花费的时间和另外两个点从各自初始位置到终点位置花费的时间相同,所以第一个点的运动速度要是其他两个点的二倍

自定义控件

创建PointProgress类,并定义各个属性,完成初始化工作

1.属性字段,attrs_point_progreess.xml

<resources>
    <declare-styleable name="PointProgreess">
        <attr name="pointColor" format="color"/>
        <attr name="pointSize" format="dimension"/>
    </declare-styleable>
</resources>
    private int pointColor = Color.RED;
    private float pointSize = 30;

    final TypedArray a = getContext().obtainStyledAttributes(
                attrs, R.styleable.PointProgreess, defStyle, 0);

    pointColor = a.getColor(
                R.styleable.PointProgreess_pointColor,
                pointColor);
    pointSize = a.getDimension(
                R.styleable.PointProgreess_pointSize,
                pointSize);

    public int getPointColor() {
        return pointColor;
    }

    public void setPointColor(int pointColor) {
        this.pointColor = pointColor;
    }

    public float getPointSize() {
        return pointSize;
    }

    public void setPointSize(float pointSize) {
        this.pointSize = pointSize;
    }

2.计算控件的宽高

    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        super.onMeasure(widthMeasureSpec, heightMeasureSpec);
        int widthSize = MeasureSpec.getSize(widthMeasureSpec);
        int widthMode = MeasureSpec.getMode(widthMeasureSpec);
        int heightSize = MeasureSpec.getSize(heightMeasureSpec);
        int heightMode = MeasureSpec.getMode(heightMeasureSpec);
        if (heightMode == MeasureSpec.AT_MOST) {
            heightSize = (int) (getPaddingTop() + getPaddingBottom() + pointSize * 3);
        }
        if (widthMode == MeasureSpec.AT_MOST) {
            widthSize = (int) (getPaddingLeft() + getPaddingRight() + pointSize * 7);
        }
        setMeasuredDimension(widthSize, heightSize);
    }

3.绘制界面

    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        if (currentTime == totalTime) {
            currentTime = 0;
        }
        drawFirstPoint(canvas);
        drawSecondPoint(canvas);
        drawThridPoint(canvas);
        currentTime++;
        invalidate();
    }

其中currentTime++和invalidate()是关键,这两行代码决定了该自定义空间能够实现动画效果

绘制三个点

1.第一个点
首先,颜色的变化,规定时间内,颜色由深变浅,从255逐渐变到255/8,所以计算方式是

 int alpha = 255 - 255 * 7 / 8 * currentTime / totalTime;
 paint.setAlpha(alpha);

其次,圆心的y值变化,该点在前四分之一时间里是向上运动的,之后的四分之一时间向下运动,返回到初始值,然后的四分之一时间继续向下运动,最后的四分之一时间向上运动,所以,y值得计算方式是

 int height = 0;
        int heightSize = (int) (pointSize * 4 / totalTime);
        if (currentTime <= totalTime / 4) {
            height = getHeight() / 2 - heightSize * currentTime;
        } else if (currentTime > totalTime / 4 && currentTime <= totalTime / 2) {
            height = (int) (getHeight() / 2 - pointSize + heightSize * (currentTime - totalTime / 4));
        } else if (currentTime > totalTime / 2 && currentTime <= totalTime * 3 / 4) {
            height = (int) (getHeight() / 2 + heightSize * (currentTime - totalTime / 2));
        } else {
            height = (int) (getHeight() / 2 + pointSize - heightSize * (currentTime - totalTime * 3 / 4));
        }

最后,圆心的x值变化,该点一直向右运动,计算方式为

 int width = (int) (getWidth() / 2 - 2 * pointSize + 4 * pointSize * currentTime / totalTime);

根据计算的x值和y值绘制圆点

  canvas.drawCircle(width, height, pointSize / 2, paint);

2.第二个点
首先,颜色的变化,规定时间内,颜色由浅变深,从255/2逐渐变到255,所以计算方式是

 int alpha = 255 / 2 + 255 * 7 / 16 * currentTime / totalTime;
 paint.setAlpha(alpha);

其次,圆心的y值变化,该点在前二分之一时间里是向下运动的,之后的二分之一时间向上运动,所以,y值得计算方式是

 int height = 0;
        int heightSize = (int) (pointSize * 2 / totalTime);
        if (currentTime <= totalTime / 2) {
            height = getHeight() / 2 + heightSize * currentTime;
        } else {
            height = (int) (getHeight() / 2 + pointSize - heightSize * (currentTime - totalTime / 2));
        }

最后,圆心的x值变化,该点一直向左运动,计算方式为

 int width = (int) (getWidth() / 2 - 2 * pointSize * currentTime / totalTime);

根据计算的x值和y值绘制圆点

  canvas.drawCircle(width, height, pointSize / 2, paint);

3.第三个点
首先,颜色的变化,规定时间内,颜色由浅变深,从255/8逐渐变到255/2,所以计算方式是

 int alpha = 255 / 2 + 255 * 7 / 16 * currentTime / totalTime;
 paint.setAlpha(alpha);

其次,圆心的y值变化,该点在前二分之一时间里是向上运动的,之后的二分之一时间向下运动,所以,y值得计算方式是

 int height = 0;
        int heightSize = (int) (pointSize * 2 / totalTime);
        if (currentTime <= totalTime / 2) {
            height = getHeight() / 2 + heightSize * currentTime;
        } else {
            height = (int) (getHeight() / 2 + pointSize - heightSize * (currentTime - totalTime / 2));
        }

最后,圆心的x值变化,该点一直向左运动,计算方式为

 int width = (int) (getWidth() / 2 - 2 * pointSize * currentTime / totalTime);

根据计算的x值和y值绘制圆点

  canvas.drawCircle(width, height, pointSize / 2, paint
);

源码地址:http://download.csdn.net/detail/krubo1/9503321

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值