本文实例为大家分享了Android实现圆形进度条的具体代码,供大家参考,具体内容如下
实现的效果图如下所示:
第一步:绘制下方有缺口的空心圆,称为外围大弧吧
复制代码
1anvas.clipRect(0, 0, mWidth, mHeight / 2 + radius - textHeight * 3 / 4);
第二步:计算绘制圆弧进度条时的起始角度,设置为外围大弧的左端点为进度值得起点,扫过的角度所占外围大弧的百分比就是进度值
第三步:绘制数字、文字、百分号
第四步:使用Handler Runnable 和DecelerateInterpolator是进度条和数字动起来
测试代码:
复制代码
1
2
3
4
5
6
7
8
9
10
11final CustomCircleBar circle=(CustomCircleBar)findViewById(R.id.win_home); circle.setPercent(10); circle.setCustomText("呵呵"); circle.setProgessColor(getResources().getColor(R.color.blue)); final Random random=new Random(); circle.setOnClickListener(new View.OnClickListener(){ @Override public void onClick(View v){ circle.setPercent(random.nextInt(100)); } });
完成代码如下:
复制代码
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
216public class CustomCircleBar extends View { private Context context; /** * 进度值 */ private int percent; /** * 颜色值 */ private int mProgessColor; /** * 下边的文字名称 */ private String mCustomText; /** * 外圈圆环的画笔 */ private Paint paintBar = new Paint(); /** * 下边文字的画笔 */ private Paint paintText = new Paint(); /** * 动态获取属性值 */ private TypedValue typedValue; /** * 先加速后减速 */ DecelerateInterpolator mDecelerateInterpolator = new DecelerateInterpolator(); /** * 动画持续时间 */ private int duration = 10; private int curTime = 0; public CustomCircleBar(Context context) { super(context); this.context=context; init(); } public CustomCircleBar(Context context, AttributeSet attrs) { super(context, attrs); this.context=context; init(); } public CustomCircleBar(Context context, AttributeSet attrs, int defStyleAttr) { super(context, attrs, defStyleAttr); this.context=context; init(); } public void setPercent(int percent) { this.percent = percent; /*isShown():Returns the visibility of this view and all of its ancestors*/ if (isShown()) { /** * 设置进度后重新开始一次动画 */ curTime=0; this.invalidate(); } } public void setProgessColor(int mProgessColor) { this.mProgessColor = mProgessColor; if (isShown()) { this.invalidate(); } } public void setCustomText(String mCustomText) { this.mCustomText = mCustomText; } private Handler mHandler = new Handler(); private Runnable mAnimation = new Runnable() { @Override public void run() { if (curTime < duration) { curTime++; /** 导致重绘,调用onDraw,onDraw最后调用 * mHandler.postDelayed(mAnimation, 20);更新进度条,界面重绘 * 每次20毫秒,绘制10次,因此动画时间200毫秒 */ CustomCircleBar.this.invalidate(); } } }; private void init() { /** * 数据初始化,没有设置属性时候的默认值 */ percent = 0; mProgessColor=Color.rgb(95,112,72); mCustomText="Home"; typedValue=new TypedValue(); context.getTheme().resolveAttribute(R.attr.maintextclor,typedValue,true); } @Override protected void onDraw(Canvas canvas) { super.onDraw(canvas); float mWidth = getWidth(); float mHeight = getHeight(); /** * 下边是进度条画笔的设置 */ /** Restores the paint to its default settings. */ paintBar.reset(); /** * 圆环宽度4个像素 */ paintBar.setStrokeWidth(4); /** * 空心圆环而非填充的额扇形 */ paintBar.setStyle(Paint.Style.STROKE); paintBar.setAntiAlias(true); paintBar.setColor(mProgessColor); /** * 调整下不透明度,使边框弧和进度条区分开 */ paintBar.setAlpha(80); /** * 接下来是文字画笔的设置 */ paintText.setTextSize(20); paintText.setColor(getResources().getColor(typedValue.resourceId)); paintText.setStyle(Paint.Style.STROKE); paintText.setAntiAlias(true); /** * 从中间开始绘制文本 */ paintText.setTextAlign(Paint.Align.CENTER); /** * 测量文字大小 */ Paint.FontMetrics fontMetrics = paintText.getFontMetrics(); /** * 计算文字高度 */ float textHeight = fontMetrics.bottom - fontMetrics.top; /** * 计算圆的半径 */ float radius = Math.min(mWidth, mHeight) / 2 - 10; /* ❑ save:用来保存Canvas的状态。save之后,可以调用Canvas的平移、放缩、旋转、错切、裁剪等操作。 ❑ restore:用来恢复Canvas之前保存的状态。防止save后对Canvas执行的操作对后续的绘制有影响。*/ /*保存画布,绘制进度条*/ canvas.save(); /*clipRect:该方法用于裁剪画布,也就是设置画布的显示区域 调用clipRect()方法后,只会显示被裁剪的区域,之外的区域将不会显示 */ canvas.clipRect(0, 0, mWidth, mHeight / 2 + radius - textHeight * 3 / 4); /*因为clipRect的原因,外边的圆环下边留个缺口绘制文字*/ canvas.drawCircle(mWidth / 2, mHeight / 2, radius, paintBar); /** * 三角函数计算,下方缺口扇形的角度的一半 */ float theta_offset = (float) Math.acos((radius - textHeight / 2) / radius); /** * 大弧围成的扇形的角度 */ float theta_full = 360 - 2 * theta_offset; /** * 进度值围成的弧对应的角度 */ float thetaProcess = mDecelerateInterpolator.getInterpolation(1.0f * curTime / duration) * percent * theta_full / 100; /** * 设置进度值颜色完全不透明 */ paintBar.setAlpha(255); paintBar.setColor(mProgessColor); /** * 注意弧形的起始角度,下边因显示文字导致圆环断开成一条弧,弧有左右两个端点,从左端点开始画弧 */ canvas.drawArc(new RectF(mWidth / 2 - radius, mHeight / 2 - radius, mWidth / 2 + radius, mHeight / 2 + radius), theta_offset+90, thetaProcess, false, paintBar); /** * 恢复画布 */ canvas.restore(); /** * 开始绘制文字 */ paintText.setTextSize(20); fontMetrics = paintText.getFontMetrics(); float textBaseLineOffset = (fontMetrics.bottom - fontMetrics.top) / 2 - fontMetrics.bottom; canvas.drawText(mCustomText, mWidth / 2, mHeight / 2 + radius - textHeight / 2 + textBaseLineOffset, paintText); /** * 绘制百分号 */ paintText.setTextSize(mHeight * 1 / 8); fontMetrics = paintText.getFontMetrics(); textBaseLineOffset = (fontMetrics.bottom - fontMetrics.top) / 2 - fontMetrics.bottom; canvas.drawText("%", mWidth / 2, mHeight / 2 + radius / 3 + textBaseLineOffset, paintText); /** * 绘制百分比 */ paintText.setTextSize(mHeight * 3 / 8); canvas.drawText("" + (int)(percent*mDecelerateInterpolator.getInterpolation(1.0f * curTime / duration)), mWidth / 2, mHeight / 2, paintText); /** * 20毫秒后执行动画 */ mHandler.postDelayed(mAnimation, 20); } }
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持靠谱客。
最后
以上就是优雅胡萝卜最近收集整理的关于Android自定义控件实现带文本与数字的圆形进度条的全部内容,更多相关Android自定义控件实现带文本与数字内容请搜索靠谱客的其他文章。
本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
发表评论 取消回复