首页 > 系统 > Android > 正文

Android实现环形进度条

2019-10-21 21:47:47
字体:
来源:转载
供稿:网友

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

Android,环形进度条

定义一个attrs.xml

<?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

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); }}

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

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();  } }}

源码:下载地址

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


注:相关教程知识阅读请移步到Android开发频道。
发表评论 共有条评论
用户名: 密码:
验证码: 匿名发表