时间:2020-12-12 09:21:56 | 栏目: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(); } } }
源码:下载地址