Android自定义View弧线进度控件

内容摘要
这个是一个以弧线为依托的进度控件,主要包括了两个圆弧、一个圆、一个文本。



当我们点击开始按钮的时候,会出现一个动画,逐渐的出现进度,好了,下面开始我们的编码。
新建一个
文章正文

这个是一个以弧线为依托的进度控件,主要包括了两个圆弧、一个圆、一个文本。

 

当我们点击开始按钮的时候,会出现一个动画,逐渐的出现进度,好了,下面开始我们的编码。

新建一个类,继承自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
private Paint mArcPaint, mCirclePaint, mTextPaint, mPaint;
 
 private float length;
 
 private float mRadius;
 
 private float mCircleXY;
 
 private float mSweepValue = 0;
 
 private String mShowText = "0%";
 
 private RectF mRectF;
 
 public MViewOne(Context context, AttributeSet attrs, int defStyleAttr) {
  super(context, attrs, defStyleAttr);
  initView();
 }
 
 public MViewOne(Context context, AttributeSet attrs) {
  super(context, attrs);
  initView();
 }
 
 public MViewOne(Context context) {
  super(context);
  initView();
 }
 
 private void initView() {
  mArcPaint = new Paint();
  mArcPaint.setStrokeWidth(50);
  mArcPaint.setAntiAlias(true);
  mArcPaint.setColor(Color.GREEN);
  mArcPaint.setStyle(Style.STROKE);
 
  mCirclePaint = new Paint();
  mCirclePaint.setColor(Color.GREEN);
  mCirclePaint.setAntiAlias(true);
 
  mTextPaint = new Paint();
  mTextPaint.setAntiAlias(true);
  mTextPaint.setColor(Color.RED);
  mTextPaint.setStrokeWidth(0);
 
  mPaint = new Paint();
  mPaint.setStrokeWidth(40);
  mPaint.setAntiAlias(true);
  mPaint.setColor(Color.YELLOW);
  mPaint.setStyle(Style.STROKE);
 
 
 }

可以看到,这里一共定义了四个画笔,两个画弧形,一个画文本,还有一个绘制圆。

在我们的onSizeChange方法里面,再给变量赋值。

1
2
3
4
5
6
7
8
@Override
protected void onSizeChanged(int w, int h, int oldw, int oldh) {
 super.onSizeChanged(w, h, oldw, oldh);
 length = w;
 mCircleXY = length / 2;
 mRadius = (float) (length * 0.5 / 2);
 
}

这时候,圆的半径、圆的起绘点,都已经有值了。

下面开始绘制

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
@Override
 protected void onDraw(Canvas canvas) {
  super.onDraw(canvas);
  // 画圆
  mRectF = new RectF((float) (length * 0.1), (float) (length * 0.1),
    (float) (length * 0.9), (float) (length * 0.9));
  canvas.drawCircle(mCircleXY, mCircleXY, mRadius, mCirclePaint);
  // 画弧线
  canvas.drawArc(mRectF, 270, 360, false, mPaint);
 
  canvas.drawArc(mRectF, 270, mSweepValue, false, mArcPaint);
 
  // 绘制文字
  float textWidth = mTextPaint.measureText(mShowText); //测量字体宽度,我们需要根据字体的宽度设置在圆环中间
 
  canvas.drawText(mShowText, (int)(length/2-textWidth/2), (int)(length/2+textWidth/2) , mTextPaint);
 
 }

这个时候,全部的效果已经出来了,但是这个还是静态的,对外暴露一个方法,让数据可以动态的刷新

1
2
3
4
5
6
7
8
9
10
11
12
13
public void setProgress(float mSweepValue) {
 float a = (float) mSweepValue;
 if (a != 0) {
  this.mSweepValue = (float) (360.0 * (a / 100.0));
  mShowText = mSweepValue + "%";
  Log.e("this.mSweepValue:", this.mSweepValue + "");
 } else {
  this.mSweepValue = 25;
  mShowText = 25 + "%";
 }
 
 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
public class MViewOne extends View {
 private Paint mArcPaint, mCirclePaint, mTextPaint, mPaint;
 
 private float length;
 
 private float mRadius;
 
 private float mCircleXY;
 
 private float mSweepValue = 0;
 
 private String mShowText = "0%";
 
 private RectF mRectF;
 
 public MViewOne(Context context, AttributeSet attrs, int defStyleAttr) {
  super(context, attrs, defStyleAttr);
  initView();
 }
 
 public MViewOne(Context context, AttributeSet attrs) {
  super(context, attrs);
  initView();
 }
 
 public MViewOne(Context context) {
  super(context);
  initView();
 }
 
 private void initView() {
  mArcPaint = new Paint();
  mArcPaint.setStrokeWidth(50);
  mArcPaint.setAntiAlias(true);
  mArcPaint.setColor(Color.GREEN);
  mArcPaint.setStyle(Style.STROKE);
 
  mCirclePaint = new Paint();
  mCirclePaint.setColor(Color.GREEN);
  mCirclePaint.setAntiAlias(true);
 
  mTextPaint = new Paint();
  mTextPaint.setAntiAlias(true);
  mTextPaint.setColor(Color.RED);
  mTextPaint.setStrokeWidth(0);
 
  mPaint = new Paint();
  mPaint.setStrokeWidth(40);
  mPaint.setAntiAlias(true);
  mPaint.setColor(Color.YELLOW);
  mPaint.setStyle(Style.STROKE);
 
 
 }
 
 @Override
 protected void onSizeChanged(int w, int h, int oldw, int oldh) {
  super.onSizeChanged(w, h, oldw, oldh);
  length = w;
  mCircleXY = length / 2;
  mRadius = (float) (length * 0.5 / 2);
 
 }
 
 @Override
 protected void onDraw(Canvas canvas) {
  super.onDraw(canvas);
  // 画圆
  mRectF = new RectF((float) (length * 0.1), (float) (length * 0.1),
    (float) (length * 0.9), (float) (length * 0.9));
  canvas.drawCircle(mCircleXY, mCircleXY, mRadius, mCirclePaint);
  // 画弧线
  canvas.drawArc(mRectF, 270, 360, false, mPaint);
 
  canvas.drawArc(mRectF, 270, mSweepValue, false, mArcPaint);
 
  // 绘制文字
  float textWidth = mTextPaint.measureText(mShowText); //测量字体宽度,我们需要根据字体的宽度设置在圆环中间
 
  canvas.drawText(mShowText, (int)(length/2-textWidth/2), (int)(length/2+textWidth/2) , mTextPaint);
 
 }
 
 public void setProgress(float mSweepValue) {
  float a = (float) mSweepValue;
  if (a != 0) {
   this.mSweepValue = (float) (360.0 * (a / 100.0));
   mShowText = mSweepValue + "%";
   Log.e("this.mSweepValue:", this.mSweepValue + "");
  } else {
   this.mSweepValue = 25;
   mShowText = 25 + "%";
  }
 
  invalidate();
 }
 
}

谢谢阅读,学习重在坚持,贵在坚持。

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


代码注释

作者:喵哥笔记

IDC笔记

学的不仅是技术,更是梦想!