自定义view————进度条

自定义view————进度条

废话不多说先看效果图

效果图

原谅模拟器显示的不好看,为了录GIF图,只能用模拟器

思路分析

一个背景,一个进度,一个进度值显示,进度条与文字显示的高度是1:2,其中用到了drawRoundRect用来画带圆角的矩形,空心与实心都是Paint的属性设置的,drawText用来画文字

注意点:

1.进度条进度满进度与未满进度,计算onewidth = mwidth / mMaxProgress(单位进度占的宽度=总宽度/满进度);
2.文字显示,先计算文字的宽度,三个状态(起始位置 <= 文字宽度 / 当前位置 +文字宽度>=宽度/之间的),分别进行计算

实现

onDraw来画图了

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
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
float x = onewidth * mCurrentProgress;
//画背景
RectF rectF = new RectF(0, 0, mwidth, bheight);
canvas.drawRoundRect(rectF, num8, num8, backgroudPaint);
//画进度条
RectF rectFm;
if (mCurrentProgress == mMaxProgress) {
rectFm = new RectF(num2, num2, mwidth - num2, bheight - num2);
} else {
rectFm = new RectF(num2, num2, x + num2, bheight - num2);
}
canvas.drawRoundRect(rectFm, num8, num8, mPaint);
//画文字
//获取文字的宽度及其高度
Rect rect = new Rect();
String speed = mCurrentProgress + "%";
txtPaint.getTextBounds(speed, 0, speed.length(), rect);
textheight = rect.height();
textwidth = rect.width();
if (mCurrentProgress == mMaxProgress) {
canvas.drawText(speed, mwidth - textwidth, txtheight, txtPaint);
} else {
//起始位置 <= 文字宽度
if (x <= textwidth) {
canvas.drawText(speed, textwidth / 2, txtheight, txtPaint);
//当前位置 +文字宽度>=宽度
} else if (x + textwidth >= mwidth) {
canvas.drawText(speed, mwidth - textwidth - 2 * num8, txtheight, txtPaint);
} else {
canvas.drawText(speed, x - textwidth / 2, txtheight, txtPaint);
}
}
}

设置进度

1
2
3
4
5
6
public void setProgress(int progress) {
if (progress <= 100 && progress >= 0) {
this.mCurrentProgress = progress;
invalidate();
}
}

实际项目中,可有很多的扩展,但是有时候实际项目不需要把很多不需要的方法,设置属性的方法等给写出来,根据项目的需求去写相关方法、属性设置

完整代码

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
/**
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package com.numberview;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Rect;
import android.graphics.RectF;
import android.support.annotation.Nullable;
import android.util.AttributeSet;
import android.view.View;
/**
* Created by wujun on 2017/9/20.
*
* @author madreain
* @desc
*/
public class NumberView1 extends View {
Paint backgroudPaint;
Paint mPaint;
Paint txtPaint;
//宽高
int mwidth, mheight;
int bheight, txtheight;
private int mMaxProgress = 100;
private int mCurrentProgress = 0;
private float onewidth;
//文字显示的宽高
int textheight;
int textwidth;
float num8;
float num2;
// 30 10 20
public NumberView1(Context context) {
super(context);
init();
}
public NumberView1(Context context, @Nullable AttributeSet attrs) {
super(context, attrs);
init();
}
public NumberView1(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
init();
}
private void init() {
backgroudPaint = new Paint();
backgroudPaint.setAntiAlias(true);
backgroudPaint.setStyle(Paint.Style.STROKE);
backgroudPaint.setStrokeCap(Paint.Cap.ROUND);
backgroudPaint.setColor(Color.rgb(51, 197, 167));
txtPaint = new Paint();
txtPaint.setAntiAlias(true);
txtPaint.setStyle(Paint.Style.FILL);
txtPaint.setColor(Color.rgb(51, 197, 167));
txtPaint.setTextSize(sp2px(12));
txtPaint.setStrokeWidth(2);
mPaint = new Paint();
mPaint.setAntiAlias(true);
mPaint.setStyle(Paint.Style.FILL);
mPaint.setStrokeCap(Paint.Cap.ROUND);
mPaint.setColor(Color.rgb(51, 197, 167));
num8 = dp2px(8);
num2 = dp2px(2);
}
@Override
protected void onSizeChanged(int w, int h, int oldw, int oldh) {
super.onSizeChanged(w, h, oldw, oldh);
mwidth = w;
mheight = h;
bheight = mheight / 3;
txtheight = bheight * 2;
onewidth = mwidth / mMaxProgress;
}
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
float x = onewidth * mCurrentProgress;
//画背景
RectF rectF = new RectF(0, 0, mwidth, bheight);
canvas.drawRoundRect(rectF, num8, num8, backgroudPaint);
//画进度条
RectF rectFm;
if (mCurrentProgress == mMaxProgress) {
rectFm = new RectF(num2, num2, mwidth - num2, bheight - num2);
} else {
rectFm = new RectF(num2, num2, x + num2, bheight - num2);
}
canvas.drawRoundRect(rectFm, num8, num8, mPaint);
//画文字
//获取文字的宽度及其高度
Rect rect = new Rect();
String speed = mCurrentProgress + "%";
txtPaint.getTextBounds(speed, 0, speed.length(), rect);
textheight = rect.height();
textwidth = rect.width();
if (mCurrentProgress == mMaxProgress) {
canvas.drawText(speed, mwidth - textwidth, txtheight, txtPaint);
} else {
//起始位置 <= 文字宽度
if (x <= textwidth) {
canvas.drawText(speed, textwidth / 2, txtheight, txtPaint);
//当前位置 +文字宽度>=宽度
} else if (x + textwidth >= mwidth) {
canvas.drawText(speed, mwidth - textwidth - 2 * num8, txtheight, txtPaint);
} else {
canvas.drawText(speed, x - textwidth / 2, txtheight, txtPaint);
}
}
}
public float dp2px(float dp) {
final float scale = getResources().getDisplayMetrics().density;
return dp * scale + 0.5f;
}
public float sp2px(float sp) {
final float scale = getResources().getDisplayMetrics().scaledDensity;
return sp * scale;
}
public void setProgress(int progress) {
if (progress <= 100 && progress >= 0) {
this.mCurrentProgress = progress;
invalidate();
}
}
}

自定义view多写多练

NumberView github demo地址

坚持原创技术分享,您的支持将鼓励我继续创作!
Fork me on GitHub