服务器之家:专注于服务器技术及软件下载分享
分类导航

PHP教程|ASP.NET教程|Java教程|ASP教程|编程技术|正则表达式|C/C++|IOS|C#|Swift|Android|VB|R语言|JavaScript|易语言|vb.net|

服务器之家 - 编程语言 - Android - Android实现环形进度条

Android实现环形进度条

2022-03-10 15:07qq_14876133 Android

这篇文章主要为大家详细介绍了Android实现环形进度条,具有一定的参考价值,感兴趣的小伙伴们可以参考一下

一个通俗易懂的环形进度条,可以定制颜色角度,监听进度。

Android实现环形进度条

定义一个attrs.xml

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
<?xml version="1.0" encoding="utf-8"?>
<resources>
 <declare-styleable name="CircleProgressView">
  <!--画笔宽度-->
  <attr name="progress_width" format="dimension" />
  <!--画笔颜色-->
  <attr name="progress_color" format="color" />
  <!--加载进度起始位置-->
  <attr name="location_start" format="enum">
   <enum name="left" value="1" />
   <enum name="top" value="2" />
   <enum name="right" value="3" />
   <enum name="bottom" value="4" />
  </attr>
 </declare-styleable>
</resources>

自定义CircleProgressView

?
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
package com.sample.circleprogressview.widget;
 
import android.animation.ValueAnimator;
import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.RectF;
import android.support.annotation.Nullable;
import android.util.AttributeSet;
import android.view.View;
import android.view.animation.LinearInterpolator;
 
import com.sample.circleprogressview.R;
 
 
/**
 * 普通环形进度条
 */
public class CircleProgressView extends View {
 private int mCurrent;//当前进度
 private Paint mBgPaint;//背景弧线paint
 private Paint mProgressPaint;//进度Paint
 private float mProgressWidth;//进度条宽度
 private int mProgressColor = Color.RED;//进度条颜色
 private int locationStart;//起始位置
 private float startAngle;//开始角度
 private ValueAnimator mAnimator;
 
 public CircleProgressView(Context context) {
  this(context, null);
 }
 
 public CircleProgressView(Context context, @Nullable AttributeSet attrs) {
  this(context, attrs, 0);
 }
 
 public CircleProgressView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
  super(context, attrs, defStyleAttr);
  init(context, attrs);
 }
 
 private void init(Context context, AttributeSet attrs) {
  TypedArray typedArray = context.obtainStyledAttributes(attrs, R.styleable.CircleProgressView);
  locationStart = typedArray.getInt(R.styleable.CircleProgressView_location_start, 1);
  mProgressWidth = typedArray.getDimension(R.styleable.CircleProgressView_progress_width, dp2px(context, 4));
  mProgressColor = typedArray.getColor(R.styleable.CircleProgressView_progress_color, mProgressColor);
  typedArray.recycle();
 
  //背景圆弧
  mBgPaint = new Paint();
  mBgPaint.setAntiAlias(true);
  mBgPaint.setStrokeWidth(mProgressWidth);
  mBgPaint.setStyle(Paint.Style.STROKE);
  mBgPaint.setColor(Color.parseColor("#eaecf0"));
  mBgPaint.setStrokeCap(Paint.Cap.ROUND);
 
  //进度圆弧
  mProgressPaint = new Paint();
  mProgressPaint.setAntiAlias(true);
  mProgressPaint.setStyle(Paint.Style.STROKE);
  mProgressPaint.setStrokeWidth(mProgressWidth);
  mProgressPaint.setColor(mProgressColor);
  mProgressPaint.setStrokeCap(Paint.Cap.ROUND);
 
  //进度条起始角度
  if (locationStart == 1) {//左
   startAngle = -180;
  } else if (locationStart == 2) {//上
   startAngle = -90;
  } else if (locationStart == 3) {//右
   startAngle = 0;
  } else if (locationStart == 4) {//下
   startAngle = 90;
  }
 }
 
 @Override
 protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
  int width = MeasureSpec.getSize(widthMeasureSpec);
  int height = MeasureSpec.getSize(heightMeasureSpec);
  int size = width < height ? width : height;
  setMeasuredDimension(size, size);
 }
 
 /**
  * oval // 绘制范围
  * startAngle // 开始角度
  * sweepAngle // 扫过角度
  * useCenter // 是否使用中心
  */
 @Override
 protected void onDraw(Canvas canvas) {
  //绘制背景圆弧
  RectF rectF = new RectF(mProgressWidth / 2, mProgressWidth / 2, getWidth() - mProgressWidth / 2, getHeight() - mProgressWidth / 2);
  canvas.drawArc(rectF, 0, 360, false, mBgPaint);
 
  //绘制当前进度
  float sweepAngle = 360 * mCurrent / 100;
  canvas.drawArc(rectF, startAngle, sweepAngle, false, mProgressPaint);
 }
 
 public int getCurrent() {
  return mCurrent;
 }
 
 /**
  * 设置进度
  *
  * @param current
  */
 public void setCurrent(int current) {
  mCurrent = current;
  invalidate();
 }
 
 private int tCurrent = -1;
 
 /**
  * 动画效果
  *
  * @param current 精度条进度:0-100
  * @param duration 动画时间
  */
 public void startAnimProgress(int current, int duration) {
  mAnimator = ValueAnimator.ofInt(0, current);
  mAnimator.setDuration(duration);
  mAnimator.setInterpolator(new LinearInterpolator());
  mAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
   @Override
   public void onAnimationUpdate(ValueAnimator animation) {
    int current = (int) animation.getAnimatedValue();
    if (tCurrent != current) {
     tCurrent = current;
     setCurrent(current);
     if (mOnAnimProgressListener != null)
      mOnAnimProgressListener.valueUpdate(current);
    }
   }
  });
  mAnimator.start();
 }
 
 public interface OnAnimProgressListener {
  void valueUpdate(int progress);
 }
 
 private OnAnimProgressListener mOnAnimProgressListener;
 
 /**
  * 监听进度条进度
  *
  * @param onAnimProgressListener
  */
 public void setOnAnimProgressListener(OnAnimProgressListener onAnimProgressListener) {
  mOnAnimProgressListener = onAnimProgressListener;
 }
 
 public void destroy() {
  if (mAnimator != null) {
   mAnimator.cancel();
  }
 }
 
 public static int dp2px(Context context, float dpValue) {
  final float scale = context.getResources().getDisplayMetrics().density;
  return (int) (dpValue * scale + 0.5f);
 }
}

代码就这么些,接下来我们测算一下

?
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
package com.sample.circleprogressview;
 
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;
 
import com.sample.circleprogressview.widget.CircleProgressView;
 
public class MainActivity extends AppCompatActivity implements View.OnClickListener {
 
 private CircleProgressView circle_progress;
 private TextView tv_progress;
 private Button btn_start;
 private Button btn_reset;
 
 @Override
 protected void onCreate(Bundle savedInstanceState) {
  super.onCreate(savedInstanceState);
  setContentView(R.layout.activity_main);
 
  btn_start = (Button) findViewById(R.id.btn_start);
  btn_reset = (Button) findViewById(R.id.btn_reset);
  circle_progress = (CircleProgressView) findViewById(R.id.circle_progress);
  tv_progress = (TextView) findViewById(R.id.tv_progress);
 
  btn_start.setOnClickListener(this);
  btn_reset.setOnClickListener(this);
 }
 
 @Override
 public void onClick(View v) {
  switch (v.getId()) {
   case R.id.btn_start:
    //开锁执行动画效果
    circle_progress.startAnimProgress(50, 1200);
    //监听进度条进度
    circle_progress.setOnAnimProgressListener(new CircleProgressView.OnAnimProgressListener() {
     @Override
     public void valueUpdate(int progress) {
      tv_progress.setText(String.valueOf(progress));
     }
    });
    break;
   case R.id.btn_reset:
    circle_progress.setCurrent(0);
    tv_progress.setText("0");
    break;
  }
 }
 
 @Override
 protected void onDestroy() {
  super.onDestroy();
  if (circle_progress != null) {
   circle_progress.destroy();
  }
 }
}

源码:下载地址

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

原文链接:https://blog.csdn.net/qq_14876133/article/details/80927243

延伸 · 阅读

精彩推荐