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

来源:互联网 发布:小世界网络的度分布 编辑:程序博客网 时间:2024/06/06 08:59

在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

0 0
原创粉丝点击