我是靠谱客的博主 如意大侠,这篇文章主要介绍Android自定义控件之水平圆点加载进度条,现在分享给大家,希望可以做个参考。

本文实例为大家分享了Android实现水平圆点加载进度条的具体代码,供大家参考,具体内容如下

先来看看要实现的效果

实现思路非常简单:当前变化的圆点先从最小半径变大到最大最大半径再变回最小半径的圆,然后再切换到下个圆点,同时颜色会先变浅在变会原来的颜色(可以理解为透明度变化),而且当前圆点的上上一个圆点颜色会不断变浅。大概就这样(可能我实现的效果和图片的有些出入)

先看下实现效果:

直接上代码: 

复制代码
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
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
package com.kincai.testcustomview_pointprogress; import android.content.Context; import android.content.res.TypedArray; import android.graphics.Canvas; import android.graphics.Paint; import android.support.annotation.Nullable; import android.support.v4.content.ContextCompat; import android.util.AttributeSet; import android.util.Log; import android.view.View; /** * Copyright (C) 2015 The KINCAI Open Source Project * . * Create By KINCAI * . * Time 2017-06-14 10:23 * . * Desc 水平圆点进度条 */ public class DotPollingView extends View { private final String TAG = this.getClass().getSimpleName(); /** * 进度当前圆点画笔和正常圆点画笔 */ private Paint mSelectedPaint = new Paint(), mNormalPaint = new Paint(); /** * 正常圆点颜色 */ private int mColor; /** * 变大圆点的颜色 */ private int mSelectedColor; /** * 圆点总数 */ private int mDotTotalCount = 3; /** * 正常圆点半径 */ private int mDotRadius; /** * 当前变化的圆点半径变化量 0.0 - (mDotMaxRadius - mDotRadius)之间 */ private float mDotCurrentRadiusChange; /** * 圆点大小变化率 */ private float mRadiusChangeRate; /** * 最大圆点半径 */ private int mDotMaxRadius; /** * 圆点最大间距 */ private int mDotSpacing; /** * 当前变大的圆点索引 */ private int mCurrentDot = 0; private int mAlphaChange = 0; private int mAlphaChangeTotal = 220; private final int DOT_STATUS_BIG = 0X101; private final int DOT_STATUS_SMALL = 0X102; private int mDotChangeStatus = DOT_STATUS_BIG; public void setColor(int mColor) { this.mColor = mColor; mNormalPaint.setColor(mColor); } public void setSelectedColor(int mSelectedColor) { this.mSelectedColor = mSelectedColor; mSelectedPaint.setColor(mSelectedColor); } public void setDotTotalCount(int mDotTotalCount) { this.mDotTotalCount = mDotTotalCount; } public void setDotRadius(int mDotRadius) { this.mDotRadius = mDotRadius; } public void setRadiusChangeRate(float mRadiusChangeRate) { this.mRadiusChangeRate = mRadiusChangeRate; } public void setDotMaxRadius(int mDotMaxRadius) { this.mDotMaxRadius = mDotMaxRadius; } public void setDotSpacing(int mDotSpacing) { this.mDotSpacing = mDotSpacing; } public DotPollingView(Context context) { this(context, null); } public DotPollingView(Context context, @Nullable AttributeSet attrs) { this(context, attrs, 0); } public DotPollingView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) { super(context, attrs, defStyleAttr); TypedArray typedArray = context.obtainStyledAttributes(attrs, R.styleable.DotPollingView, defStyleAttr, 0); initAttributes(typedArray); typedArray.recycle(); init(); } private void initAttributes(TypedArray Attributes) { mColor = Attributes.getColor(R.styleable.DotPollingView_dotP_dot_color, ContextCompat.getColor(getContext(),R.color.colorPrimary)); mSelectedColor = Attributes.getColor(R.styleable.DotPollingView_dotP_dot_selected_color, ContextCompat.getColor(getContext(),R.color.colorAccent)); mDotRadius = Attributes.getDimensionPixelSize(R.styleable.DotPollingView_dotP_dot_radius,DensityUtils.dp2px(getContext(),3)); mDotMaxRadius = Attributes.getDimensionPixelSize(R.styleable.DotPollingView_dotP_dot_max_radius,DensityUtils.dp2px(getContext(),5)); mDotSpacing = Attributes.getDimensionPixelSize(R.styleable.DotPollingView_dotP_dot_spacing,DensityUtils.dp2px(getContext(),6)); mDotTotalCount = Attributes.getInteger(R.styleable.DotPollingView_dotP_dot_count,3); mRadiusChangeRate = Attributes.getFloat(R.styleable.DotPollingView_dotP_dot_size_change_rate,0.3f); } /** * 初始化 */ private void init() { mDotCurrentRadiusChange = 0f; mSelectedPaint.setColor(mSelectedColor); mSelectedPaint.setAntiAlias(true); mSelectedPaint.setStyle(Paint.Style.FILL); mNormalPaint.setColor(mColor); mNormalPaint.setAntiAlias(true); mNormalPaint.setStyle(Paint.Style.FILL); } @Override protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { //测量宽高 int widthMode = MeasureSpec.getMode(widthMeasureSpec); int widthSize = MeasureSpec.getSize(widthMeasureSpec); int heightMode = MeasureSpec.getMode(heightMeasureSpec); int heightSize = MeasureSpec.getSize(heightMeasureSpec); int width; int height; if(widthMode == MeasureSpec.EXACTLY) { width = widthSize; Log.e(TAG, "onMeasure MeasureSpec.EXACTLY widthSize="+widthSize); } else { //指定最小宽度所有圆点加上间距的宽度, 以最小半径加上间距算总和再加上最左边和最右边变大后的距离 width = (mDotTotalCount * mDotRadius * 2 + ((mDotTotalCount - 1) * mDotSpacing)) + (mDotMaxRadius - mDotRadius) * 2; Log.e(TAG, "onMeasure no MeasureSpec.EXACTLY widthSize="+widthSize+" width="+width); if(widthMode == MeasureSpec.AT_MOST) { width = Math.min(width, widthSize); Log.e(TAG, "onMeasure MeasureSpec.AT_MOST width="+width); } } if(heightMode == MeasureSpec.EXACTLY) { height = heightSize; Log.e(TAG, "onMeasure MeasureSpec.EXACTLY heightSize="+heightSize); } else { height = mDotMaxRadius * 2; Log.e(TAG, "onMeasure no MeasureSpec.EXACTLY heightSize="+heightSize+" height="+height); if(heightMode == MeasureSpec.AT_MOST) { height = Math.min(height, heightSize); Log.e(TAG, "onMeasure MeasureSpec.AT_MOST height="+height); } } setMeasuredDimension(width,height); } @Override protected void onDraw(Canvas canvas) { super.onDraw(canvas); mNormalPaint.setAlpha(255); mSelectedPaint.setAlpha(255); if(mDotChangeStatus == DOT_STATUS_BIG) { mDotCurrentRadiusChange += mRadiusChangeRate; mAlphaChange +=12; } else { mDotCurrentRadiusChange -= mRadiusChangeRate; mAlphaChange -=12; } if(mAlphaChange >= mAlphaChangeTotal) { mAlphaChange = mAlphaChangeTotal; } Log.e("DotPollingView", "dot current radius change: " + mDotCurrentRadiusChange); //第一个圆点的圆心x坐标计算:控件宽度的一半减去(所有圆点直径的和以及所有间距的和相加的总和的一半)再加上一个半径大小 // ,为什么要加上半径?因为我们起点要的是圆心,但算出来的是最左边x坐标 int startPointX = getWidth() / 2 - (mDotTotalCount * mDotRadius * 2 + ((mDotTotalCount - 1) * mDotSpacing)) / 2 + mDotRadius; //所有圆点的圆心y坐标一致控件高度的一半 int startPointY = getHeight() / 2; for (int i = 0; i < mDotTotalCount; i++) { if(mCurrentDot == i) {//当前圆点 mSelectedPaint.setAlpha(255 - mAlphaChange); canvas.drawCircle(startPointX + mCurrentDot * (mDotRadius * 2 + mDotSpacing), startPointY , mDotRadius + mDotCurrentRadiusChange, mSelectedPaint); continue; } else if(mCurrentDot > 1 && mCurrentDot - 2 == i) {//当前圆点前两个 mNormalPaint.setAlpha(255 - mAlphaChange); canvas.drawCircle(startPointX + (mCurrentDot - 2) * (mDotRadius * 2 + mDotSpacing), startPointY, mDotRadius, mNormalPaint); continue; } //画正常的圆点 mNormalPaint.setAlpha(255); canvas.drawCircle(startPointX + i * (mDotRadius * 2 + mDotSpacing), startPointY, mDotRadius, mNormalPaint); } //当圆点变化率达到最大或超过最大半径和正常半径之差时 变化率重置0,当前变大圆点移至下一圆点 if (mDotCurrentRadiusChange >= (mDotMaxRadius - mDotRadius) && mDotChangeStatus == DOT_STATUS_BIG) { mDotCurrentRadiusChange = mDotMaxRadius - mDotRadius; mDotChangeStatus = DOT_STATUS_SMALL; } else if(mDotCurrentRadiusChange <= 0 && mDotChangeStatus == DOT_STATUS_SMALL) { mDotChangeStatus = DOT_STATUS_BIG; mDotCurrentRadiusChange = 0f; mCurrentDot = mCurrentDot == mDotTotalCount - 1 ? 0 : mCurrentDot + 1; mAlphaChange = 0; } invalidate(); } }

源码下载github:TestCustomView_PointProgress

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持靠谱客。

最后

以上就是如意大侠最近收集整理的关于Android自定义控件之水平圆点加载进度条的全部内容,更多相关Android自定义控件之水平圆点加载进度条内容请搜索靠谱客的其他文章。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(129)

评论列表共有 0 条评论

立即
投稿
返回
顶部