天看到一个银行的APP上面的loadingview 挺好的,就尝试着自己实现,觉得很简单,但自己实现起来还是发现了一些问题。LoadingView和下图类似:
实现的代码也不是很复杂,就是小球的运动轨迹需要计算,我自己手画了个计算的图,很简单的就是三角函数的使用。
然后代码就是代码实现了,主要的内容都有注释,代码如下:
ublic class LoadingView extends View {
private final static String TAG = "LoadingView";
private final static int LEFT_BALL_DOWN = 1;
private final static int LEFT_BALL_UP = 2;
private final static int RIGHT_BALL_DOWN = 3;
private final static int RIGHT_BALL_UP = 4;
private Paint paint1, paint2, paint3, paint4, paint5;
private int mCurrentAnimatorValue;
private int circleRadius = 10; //小球的半径
private int distance = 60; //小球开始下落到最低点的距离
private int mCurrentState = LEFT_BALL_DOWN;
public LoadingView(Context context) {
super(context);
init(context);
}
public LoadingView(Context context, @Nullable AttributeSet attrs) {
super(context, attrs);
init(context);
}
public LoadingView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
init(context);
}
private void init(Context context) {
paint1 = getPaint(Color.RED);
paint2 = getPaint(Color.YELLOW);
paint3 = getPaint(Color.GREEN);
paint4 = getPaint(Color.BLUE);
paint5 = getPaint(Color.CYAN);
ValueAnimator animator = ValueAnimator.ofInt(0, 90);
animator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
@Override
public void onAnimationUpdate(ValueAnimator animation) {
mCurrentAnimatorValue = (int) animation.getAnimatedValue();
Log.e(TAG, "onAnimationUpdate : mCurrentAnimatorValue = " + mCurrentAnimatorValue);
invalidate();
}
});
animator.addListener(new Animator.AnimatorListener() {
@Override
public void onAnimationStart(Animator animation) {
}
@Override
public void onAnimationEnd(Animator animation) {
}
@Override
public void onAnimationCancel(Animator animation) {
}
@Override
public void onAnimationRepeat(Animator animation) {
Log.e(TAG, "onAnimationRepeat : mCurrentAnimatorValue = " + mCurrentAnimatorValue);
switch (mCurrentState) {
case LEFT_BALL_DOWN:
mCurrentState = RIGHT_BALL_UP;
break;
case RIGHT_BALL_UP:
mCurrentState = RIGHT_BALL_DOWN;
break;
case RIGHT_BALL_DOWN:
mCurrentState = LEFT_BALL_UP;
break;
case LEFT_BALL_UP:
mCurrentState = LEFT_BALL_DOWN;
break;
}
}
});
animator.setStartDelay(500);
animator.setDuration(600);
animator.setRepeatCount(ValueAnimator.INFINITE);
animator.setInterpolator(new DecelerateInterpolator());
animator.start();
}
private Paint getPaint(int color) {
Paint paint = new Paint();
paint.setColor(color);
paint.setAntiAlias(true);
paint.setStyle(Paint.Style.FILL);
return paint;
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
}
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
int x, y;
double cosValue = Math.cos(PI * mCurrentAnimatorValue / 180);
double sinValue = Math.sin(PI * mCurrentAnimatorValue / 180);
drawFourBall(canvas);
switch (mCurrentState) {
case LEFT_BALL_DOWN://最左边小球往下撞击
x = circleRadius + (int) ((distance - circleRadius) * (1 - cosValue));
y = getHeight() - distance + (int) ((distance - circleRadius) * sinValue);
canvas.drawCircle(x, y, circleRadius, paint1);
break;
case RIGHT_BALL_UP://最右边小球往上撞击
x = distance + 8 * circleRadius + (int) ((distance - circleRadius) * sinValue);
y = getHeight() - distance + (int) (cosValue * (distance - circleRadius));
canvas.drawCircle(x, y, circleRadius, paint5);
break;
case RIGHT_BALL_DOWN://最右边小球往下撞击
x = distance + 8 * circleRadius + (int) ((distance - circleRadius) * (cosValue));
y = (getHeight() - distance) + (int) ((distance - circleRadius) * (sinValue));
canvas.drawCircle(x, y, circleRadius, paint5);
break;
case LEFT_BALL_UP://最左边小球往上撞击
x = distance - (int) ((distance - circleRadius) * sinValue);
y = getHeight() - distance + (int) ((distance - circleRadius) * cosValue);
canvas.drawCircle(x, y, circleRadius, paint1);
break;
}
}
private void drawFourBall(Canvas canvas) {
int y = getHeight() - circleRadius;
canvas.drawCircle(distance + 2 * circleRadius, y, circleRadius, paint2);
canvas.drawCircle(distance + 4 * circleRadius, y, circleRadius, paint3);
canvas.drawCircle(distance + 6 * circleRadius, y, circleRadius, paint4);
if (mCurrentState == LEFT_BALL_DOWN || mCurrentState == LEFT_BALL_UP) {//最左边球运动的时候,要绘制最右边的球
canvas.drawCircle(distance + 8 * circleRadius, y, circleRadius, paint5);
} else if (mCurrentState == RIGHT_BALL_UP || mCurrentState == RIGHT_BALL_DOWN) {//最右边球运动的时候,要绘制最左边的球
canvas.drawCircle(distance, y, circleRadius, paint1);
}
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
实现的效果如图一,有问题的话互相讨论。最后贴上想xml文件,后续会完善设置loadingview的大小和颜色之类的参数。
xml如下:
<com.define_view.LoadingView
android:layout_marginTop="20px"
android:background="#999999"
android:layout_width="200px"
android:layout_height="200px" />
1
2
3
4
5
————————————————
版权声明:本文为CSDN博主「小猪快跑22」的原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/zhujiangtaotaise/article/details/73610308
来源:oschina
链接:https://my.oschina.net/u/4000302/blog/3123538