码迷,mamicode.com
首页 > 其他好文 > 详细

一种加载动画的实现

时间:2015-03-29 13:41:54      阅读:120      评论:0      收藏:0      [点我收藏+]

标签:android   加载动画   loading   

技术分享

记得看过上面的一个动画设计,就试着实现了一下,首先是可以看到这个动画由两部分组成,一个圆圈的顺时针转动,另一个是圆点的直线运动,圆点之间有时间差,两种运动叠加就形成了这种滚动的效果。
技术分享 技术分享 技术分享

图一、图二、图三

上面图一显示了只有圆圈旋转的状态,图二是只有圆点直线运动的状态,图三是图二中各个圆点添加时间差后的效果。

实现

绘制点

这里一共有15个圆点,相位偏差是360/15=24?

for (int i = 0; i < POINT_NUM; ++i) {
    float x = mRadius * -(float) Math.sin(DEGREE * 24 * i);
    float y = mRadius * -(float) Math.cos(DEGREE * 24 * i);

    ArcPoint point = new ArcPoint(x, y, COLORS[i % 3]);
    mArcPoint[i] = point;
}

private final double DEGREE = Math.PI / 180;
private static final int POINT_NUM = 15;

ArcPoint是点的定义,包括位置和颜色

static class ArcPoint {
    float x;
    float y;
    int color;

    ArcPoint(float x, float y, int color) {
        this.x = x;
        this.y = y;
        this.color = color;
    }
}

绘制圆圈的旋转

可以固定点不动,通过旋转canvas来实现

    @Override
    protected void onDraw(Canvas canvas) {
        canvas.save();
        canvas.translate(mCenter.x, mCenter.y);

        float factor = getFactor();
        canvas.rotate(36 * factor);
        float x, y;
        for (int i = 0; i < POINT_NUM; ++i) {
            mPaint.setColor(mArcPoint[i].color);
            // float itemFactor = getItemFactor(i, factor);
            x = mArcPoint[i].x;// - 2 * mArcPoint[i].x * itemFactor;
            y = mArcPoint[i].y;// - 2 * mArcPoint[i].y * itemFactor;
            canvas.drawCircle(x, y, mPointRadius, mPaint);
        }

        canvas.restore();
        if (mStartAnim) {
            postInvalidate();
        }
    }

这样就可以得到图一圆圈旋转的动画,这里固定了旋转角度36,如果是360就可以看到一个完整的旋转。
这里旋转角度为什么取36?看完整效果,其实每个点在直线移动后,转动1.5个相位偏差也就是24*1.5=36,就可以和其实点的图形重合,而且因为圆点的颜色每三个重复一次,所以经过36度的旋转,新圆点位置和动画开始状态看上去就是一样的。

给圆点添加起始偏移时间

每个点运动的起始时间是不同的,如果一起运动就会得到图二的效果,我们看怎么从总的时间得到每个圆点的运动时间,也就是

float itemFactor = getItemFactor(i, factor);
private float getItemFactor(int index, float factor) {
    float itemFactor = (factor - 0.66f / POINT_NUM * index) * 3;
    if (itemFactor < 0f) {
        itemFactor = 0f;
    } else if (itemFactor > 1f) {
        itemFactor = 1f;
    }
    return mInterpolator.getInterpolation(itemFactor);
}

这里设计每个点直线运动的时间是周期的1/3,那剩余的2/3=0.66就是从第一个点开始到最后一个点开始运动的时间,通过

factor - 0.66f / POINT_NUM * index

就可以得到每个圆点的起始时间,再*3将其换算到直线运动的时间上。
将上面的运动组合起来就得到了完整的onDraw方法

    @Override
    protected void onDraw(Canvas canvas) {
        canvas.save();
        canvas.translate(mCenter.x, mCenter.y);

        float factor = getFactor();
        canvas.rotate(36 * factor);
        float x, y;
        for (int i = 0; i < POINT_NUM; ++i) {
            mPaint.setColor(mArcPoint[i].color);
            float itemFactor = getItemFactor(i, factor);
            x = mArcPoint[i].x - 2 * mArcPoint[i].x * itemFactor;
            y = mArcPoint[i].y - 2 * mArcPoint[i].y * itemFactor;
            canvas.drawCircle(x, y, mPointRadius, mPaint);
        }

        canvas.restore();
        if (mStartAnim) {
            postInvalidate();
        }
    }

Source code

源码在这里 https://github.com/Fichardu/CircleProgress

一种加载动画的实现

标签:android   加载动画   loading   

原文地址:http://blog.csdn.net/xu_fu/article/details/44725921

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!