这是第二个

这里展示了两个不同大小的View效果,当然真正的三体几乎是没有规律的
思路
1、根据View的宽高计算三个小球的初始位置
我这里是根据宽高比重计算小球的位置,先确定中间位置,为了增加容错性,三个小球的直径最大为View宽度的5/6,并且最大为Vieww高度的4/5;左右小球的圆心距离中间小球的圆心是一个小球的直径大小。
使用drawCircle绘制出来,效果是这样

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
<com.riverlet.loading.ThreeBodyLoadingView
android:layout_width="100dp"
android:layout_height="100dp"
android:layout_marginTop="50dp"
app:firstColor="#FFFF0000"
app:secondColor="#FF1C86EE"
app:thirdColor="#FFEE9A00" />
- app:firstColor,球1颜色
- app:secondColor,球2颜色
- app:thirdColor,球3颜色
代码
其他具体看代码吧:Loading
-----------------------------目录-----------------------------
1、CircleLoadingView
2、ThreeBodyLoadingView
网友评论