我是靠谱客的博主 粗暴黑夜,这篇文章主要介绍Android自定义View实现水平带数字百分比进度条,现在分享给大家,希望可以做个参考。

这个进度条可以反映真实进度,并且完成百分比的文字时随着进度增加而移动的,所在位置也恰好是真实完成的百分比位置,效果如下:


思路如下:第一部分是左侧的蓝色直线,代表已经完成的进度;第二部分是右侧灰色的直线,代表未完成的进度;第三部分是红色的百分比的数字百分比文本,显示当前确切的完成进度。

最关键的部分就是要确定百分比文本的确切位置,这里用了paint的getTextBounds方法,得到文本的宽高,然后再精确确定它的位置。

view代码如下:

复制代码
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
public class NumberProgressView extends View { /** * 进度条画笔的宽度(dp) */ private int paintProgressWidth = 3; /** * 文字百分比的字体大小(sp) */ private int paintTextSize = 20; /** * 左侧已完成进度条的颜色 */ private int paintLeftColor = 0xff67aae4; /** * 右侧未完成进度条的颜色 */ private int paintRightColor = 0xffaaaaaa; /** * 百分比文字的颜色 */ private int paintTextColor = 0xffff0077; /** * Contxt */ private Context context; /** * 主线程传过来进程 0 - 100 */ private int progress; /** * 得到自定义视图的宽度 */ private int viewWidth; /** * 得到自定义视图的Y轴中心点 */ private int viewCenterY; /** * 画左边已完成进度条的画笔 */ private Paint paintleft = new Paint(); /** * 画右边未完成进度条的画笔 */ private Paint paintRight = new Paint(); /** * 画中间的百分比文字的画笔 */ private Paint paintText = new Paint(); /** * 要画的文字的宽度 */ private int textWidth; /** * 画文字时底部的坐标 */ private float textBottomY; /** * 包裹文字的矩形 */ private Rect rect = new Rect(); /** * 文字总共移动的长度(即从0%到100%文字左侧移动的长度) */ private int totalMovedLength; public NumberProgressView(Context context, AttributeSet attrs) { super(context, attrs); this.context = context; // 构造器中初始化数据 initData(); } /** * 初始化数据 */ private void initData() { //设置进度条画笔的宽度 int paintProgressWidthPx = Utils.dip2px(context, paintProgressWidth); //设置百分比文字的尺寸 int paintTextSizePx = Utils.sp2px(context, paintTextSize); // 已完成进度条画笔的属性 paintleft.setColor(paintLeftColor); paintleft.setStrokeWidth(paintProgressWidthPx); paintleft.setAntiAlias(true); paintleft.setStyle(Style.FILL); // 未完成进度条画笔的属性 paintRight.setColor(paintRightColor); paintRight.setStrokeWidth(paintProgressWidthPx); paintRight.setAntiAlias(true); paintRight.setStyle(Style.FILL); // 百分比文字画笔的属性 paintText.setColor(paintTextColor); paintText.setTextSize(paintTextSizePx); paintText.setAntiAlias(true); paintText.setTypeface(Typeface.DEFAULT_BOLD); } @Override protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { super.onMeasure(widthMeasureSpec, heightMeasureSpec); getWidthAndHeight(); } /** * 得到视图等的高度宽度尺寸数据 */ private void getWidthAndHeight() { //得到包围文字的矩形的宽高 paintText.getTextBounds("000%", 0, "000%".length(), rect); textWidth = rect.width(); textBottomY = viewCenterY + rect.height() / 2; //得到自定义视图的高度 int viewHeight = getMeasuredHeight(); viewWidth = getMeasuredWidth(); viewCenterY = viewHeight / 2; totalMovedLength = viewWidth - textWidth; } @Override protected void onDraw(Canvas canvas) { super.onDraw(canvas); //得到float型进度 float progressFloat = progress / 100.0f; //当前文字移动的长度 float currentMovedLentgh = totalMovedLength * progressFloat; //画左侧已经完成的进度条,长度为从Veiw左端到文字的左侧 canvas.drawLine(0, viewCenterY, currentMovedLentgh, viewCenterY, paintleft); //画右侧未完成的进度条,这个进度条的长度不是严格按照百分比来缩放的,因为文字的长度会变化,所以它的长度缩放比例也会变化 if (progress < 10) { canvas.drawLine(currentMovedLentgh + textWidth * 0.5f, viewCenterY, viewWidth, viewCenterY, paintRight); } else if (progress < 100) { canvas.drawLine(currentMovedLentgh + textWidth * 0.75f, viewCenterY, viewWidth, viewCenterY, paintRight); } else { canvas.drawLine(currentMovedLentgh + textWidth, viewCenterY, viewWidth, viewCenterY, paintRight); } //画文字(注意:文字要最后画,因为文字和进度条可能会有重合部分,所以要最后画文字,用文字盖住重合的部分) canvas.drawText(progress + "%", currentMovedLentgh, textBottomY, paintText); } /** * @param progress 外部传进来的当前进度 */ public void setProgress(int progress) { this.progress = progress; invalidate(); } }

调用者activity的代码,设置进度条的进度:

复制代码
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
public class NumberProgressBarActivity extends Activity { protected static final int WHAT_INCREASE = 1; private NumberProgressView np_numberProgressBar; private int progress; private Handler handler = new Handler() { public void handleMessage(android.os.Message msg) { progress++; np_numberProgressBar.setProgress(progress); handler.sendEmptyMessageDelayed(WHAT_INCREASE, getRadomNumber(50, 200)); if (progress >= 100) { handler.removeMessages(WHAT_INCREASE); } } }; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_number_progress_bar); np_numberProgressBar = (NumberProgressView) findViewById(R.id.np_numberProgressBar); Button btn_numberProgressBar = (Button) findViewById(R.id.btn_numberProgressBar); btn_numberProgressBar.setOnClickListener(new OnClickListener() { @Override public void onClick(View v) { increase(); } }); } private void increase() { progress = 0; np_numberProgressBar.setProgress(0); handler.removeMessages(WHAT_INCREASE); handler.sendEmptyMessage(WHAT_INCREASE); } /** * 得到两个整数之间的一个随机数 * * @param start 较小的数 * @param end 较大的数 * @return */ public int getRadomNumber(int start, int end) { return (int) (start + Math.random() * (end - start)); } }

工具方法:

复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
/** * 将dip或dp值转换为px值,保证尺寸大小不变 */ public static int dip2px(Context context, float dipValue) { final float scale = context.getResources().getDisplayMetrics().density; return (int) (dipValue * scale + 0.5f); } /** * 将sp值转换为px值,保证文字大小不变 */ public static int sp2px(Context context, float spValue) { final float fontScale = context.getResources().getDisplayMetrics().scaledDensity; return (int) (spValue * fontScale + 0.5f); }

布局:

复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical"> <com.example.viewdemo.view.NumberProgressView android:id="@+id/np_numberProgressBar" android:layout_width="wrap_content" android:layout_height="100dp" android:layout_margin="20dp" android:background="#33890075" /> <Button android:id="@+id/btn_numberProgressBar" android:layout_width="match_parent" android:layout_height="wrap_content" android:text="开始"/> </LinearLayout>

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

最后

以上就是粗暴黑夜最近收集整理的关于Android自定义View实现水平带数字百分比进度条的全部内容,更多相关Android自定义View实现水平带数字百分比进度条内容请搜索靠谱客的其他文章。

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

评论列表共有 0 条评论

立即
投稿
返回
顶部