Loading(二)--ThreeBodyLoadingView

这是第二个

Loading(二)--ThreeBodyLoadingView_第1张图片
三体动画效果图.gif

这里展示了两个不同大小的View效果,当然真正的三体几乎是没有规律的

思路

1、根据View的宽高计算三个小球的初始位置

我这里是根据宽高比重计算小球的位置,先确定中间位置,为了增加容错性,三个小球的直径最大为View宽度的5/6,并且最大为Vieww高度的4/5;左右小球的圆心距离中间小球的圆心是一个小球的直径大小。
使用drawCircle绘制出来,效果是这样


Loading(二)--ThreeBodyLoadingView_第2张图片
初始效果.png

2、使用属性动画计算小球的位置和半径变化大小

我使用属性动画,改变一个rate的成员变量,使他从0到3匀速变化大小,01,12,2~3,分别对应小球运动的三个状态:左->中,中->右,右->左。

小球 位置变换
球1 左->中
球2 中->右
球3 右->左

rate数值0~1

小球 位置变换
球1 左->中
球2 中->右
球3 右->左
小球 位置变换
球1 中->右
球2 右->左
球3 左->中

rate数值1~2

小球 位置变换
球1 中->右
球2 右->左
球3 左->中
小球 位置变换
球1 右->左
球2 中->右
球3 中->右

rate数值2~3

小球 位置变换
球1 右->左
球2 中->右
球3 中->右
    /**
     * 记录三个小球的初始位置
     * Body记录小球参数的内部实体类
     */
    private Body[] originalBodys = new Body[3];
    /**
     * 记录三个小球的最新位置
     */
    private Body[] bodys = new Body[3];
//计算新位置
    private void computePosition() {
        if (rate <= 1.0f) {
            bodys[0].centerX = (int) (originalBodys[0].centerX + movingDistance * 0.5f * rate);
            bodys[0].radius = (int) (originalBodys[0].radius + radiusRange * rate);

            bodys[1].centerX = (int) (originalBodys[1].centerX + movingDistance * 0.5f * rate);
            bodys[1].radius = (int) (originalBodys[1].radius + radiusRange * (1 - rate));

            bodys[2].centerX = (int) (originalBodys[2].centerX - movingDistance * rate);
            bodys[2].radius = originalBodys[2].radius;

        } else if (rate > 1.0f && rate <= 2.0f) {          
            bodys[0].centerX = (int) (originalBodys[0].centerX + movingDistance * 0.5f + movingDistance * 0.5f * (rate - 1));
            bodys[0].radius = (int) (originalBodys[0].radius + radiusRange * (2 - rate));

            bodys[1].centerX = (int) (originalBodys[1].centerX + movingDistance * 0.5f - movingDistance * (rate - 1));
            bodys[1].radius = originalBodys[1].radius;

            bodys[2].centerX = (int) (originalBodys[2].centerX - movingDistance + movingDistance * 0.5f * (rate - 1));
            bodys[2].radius = (int) (originalBodys[2].radius + radiusRange * (rate - 1));

 
        } else if (rate > 2.0f && rate <= 3.0f) {
            bodys[0].centerX = (int) (originalBodys[0].centerX + movingDistance - movingDistance * (rate - 2));
            bodys[0].radius = originalBodys[0].radius;

            bodys[1].centerX = (int) (originalBodys[1].centerX - movingDistance * 0.5f + movingDistance * 0.5f * (rate - 2)); rate));
            bodys[1].radius = (int) (originalBodys[1].radius + radiusRange * (rate - 2));

            bodys[2].centerX = (int) (originalBodys[2].centerX - movingDistance * 0.5f + movingDistance * 0.5f * (rate - 2));
            bodys[2].radius = (int) (originalBodys[2].radius + radiusRange - radiusRange * (rate - 2));

        }
    }

3、确定绘制顺序

因为先绘制的图层会在下面,所以右->左这个运动位置的小球一定是最先绘制的

        if (rate <= 1.0f) {
            drawOrders[0] = 2;
            drawOrders[1] = 1;
            drawOrders[2] = 0;
        } else if (rate > 1.0f && rate <= 2.0f) {
            drawOrders[0] = 1;
            drawOrders[1] = 0;
            drawOrders[2] = 2;
        } else if (rate > 2.0f && rate <= 3.0f) {
            drawOrders[0] = 0;
            drawOrders[1] = 1;
            drawOrders[2] = 2;
        }

4、动画开启和结束

@Override
    protected void onAttachedToWindow() {
        super.onAttachedToWindow();
        animStart();
    }

    @Override
    protected void onDetachedFromWindow() {
        super.onDetachedFromWindow();
        animStop();
    }

使用

xml

 
  • app:firstColor,球1颜色
  • app:secondColor,球2颜色
  • app:thirdColor,球3颜色

代码

其他具体看代码吧:Loading

-----------------------------目录-----------------------------

1、CircleLoadingView
2、ThreeBodyLoadingView

你可能感兴趣的:(Loading(二)--ThreeBodyLoadingView)