Android自定义圆形进度条

github地址:https://github.com/opq1289/CircleProgressView

效果图:
无动画:
有动画:

整圆:

切割圆:

具体步骤:

1. 绘制最基础的两个圆

定义两个画笔:

//进度条画笔
mProgressPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
mProgressPaint.setStyle(Paint.Style.STROKE);
mProgressPaint.setStrokeWidth(30);
mProgressPaint.setColor(Color.parseColor("#d81b60"));
//背景圆画笔
mBackgroundPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
mBackgroundPaint.setStyle(Paint.Style.STROKE);
mBackgroundPaint.setStrokeWidth(30);
mBackgroundPaint.setColor(Color.parseColor("#f1f1f1"));
复制代码

画圆:

mRectf = new RectF(0, 0, 200, 200);
canvas.drawCircle(100, 100, 100, mBackgroundPaint);
canvas.drawArc(mRectf, 0, 120, false, mProgressPaint);
复制代码

边缘被切割,增加参数进度条宽度,优化边缘:

private void initPaint() {//进度条画笔mProgressPaint = new Paint(Paint.ANTI_ALIAS_FLAG);mProgressPaint.setStyle(Paint.Style.STROKE);mProgressPaint.setStrokeWidth(mProgressWidth);mProgressPaint.setColor(Color.parseColor("#d81b60"));//背景圆画笔mBackgroundPaint = new Paint(Paint.ANTI_ALIAS_FLAG);mBackgroundPaint.setStyle(Paint.Style.STROKE);mBackgroundPaint.setStrokeWidth(mProgressWidth);mBackgroundPaint.setColor(Color.parseColor("#f1f1f1"));
}@Override
protected void onDraw(Canvas canvas) {super.onDraw(canvas);mRectf = new RectF(mProgressWidth / 2, mProgressWidth / 2, 200 - mProgressWidth / 2, 200 - mProgressWidth / 2);canvas.drawCircle(100, 100, 100 - mProgressWidth / 2, mBackgroundPaint);canvas.drawArc(mRectf, 0, 120, false, mProgressPaint);
}
复制代码

2. 计算尺寸

main_activity.xml中的布局是:

android:layout_width="100dp"
android:layout_height="100dp"
复制代码

显示布局边界后发现view的宽高是屏幕宽高:

重新设置view的尺寸:

//设置默认最小尺寸
private int mDefaultWidth = CommonUtil.dp2px(getContext(), 10);
复制代码
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {super.onMeasure(widthMeasureSpec, heightMeasureSpec);int width = measureWidth(widthMeasureSpec);int height = measureHeight(heightMeasureSpec);mViewWidth = Math.min(width, height);setMeasuredDimension(mViewWidth, mViewWidth);
}
复制代码
private int measureWidth(int widthMeasureSpec) {int width;int size = MeasureSpec.getSize(widthMeasureSpec);int mode = MeasureSpec.getMode(widthMeasureSpec);switch (mode) {case MeasureSpec.EXACTLY:width = size < mProgressWidth ? mProgressWidth : size;break;case MeasureSpec.AT_MOST:width = mDefaultWidth * 2;break;default:width = CommonUtil.getScreenWidthInPx(getContext());break;}return width;
}private int measureHeight(int heightMeasureSpec) {int height;int size = MeasureSpec.getSize(heightMeasureSpec);int mode = MeasureSpec.getMode(heightMeasureSpec);switch (mode) {case MeasureSpec.EXACTLY:height = size < mProgressWidth ? mProgressWidth : size;break;case MeasureSpec.AT_MOST:height = mDefaultWidth * 2;break;default:height = CommonUtil.getScreenHeightInPx(getContext());break;}return height;
}
复制代码

然后修改绘制:

@Override
protected void onDraw(Canvas canvas) {super.onDraw(canvas);mRectf = new RectF(mProgressWidth / 2, mProgressWidth / 2, mViewWidth - mProgressWidth / 2, mViewWidth - mProgressWidth / 2);canvas.drawCircle(mViewWidth / 2, mViewWidth / 2, mViewWidth / 2 - mProgressWidth / 2, mBackgroundPaint);canvas.drawArc(mRectf, 0, 120, false, mProgressPaint);
}
复制代码

至此,静态进度条就画好了。

将参数设置为动态,通过方法和属性设置。

<declare-styleable name="CircleProgressView"><attr name="progressWidth" format="dimension"/><attr name="progressColor" format="reference"/><attr name="backgroundColor" format="reference"/><attr name="startAngle" format="integer"/>
</declare-styleable>复制代码
public CircleProgressView(Context context, AttributeSet attrs, int defStyleAttr) {super(context, attrs, defStyleAttr);initPaint();TypedArray typedArray = getContext().obtainStyledAttributes(attrs, R.styleable.CircleProgressView, defStyleAttr, 0);mProgressWidth = (int) typedArray.getDimension(R.styleable.CircleProgressView_progressWidth, mDefaultWidth);mProgressColor = (int) typedArray.getDimension(R.styleable.CircleProgressView_progressColor, ContextCompat.getColor(getContext(), R.color.colorAccent));mStartAngle = typedArray.getInt(R.styleable.CircleProgressView_startAngle, 0);mEndAngle = typedArray.getInt(R.styleable.CircleProgressView_startAngle, 360);mBackgroundColor = (int) typedArray.getDimension(R.styleable.CircleProgressView_backgroundColor, ContextCompat.getColor(getContext(), R.color.grey_f1));typedArray.recycle();mProgressPaint.setStrokeWidth(mProgressWidth);mProgressPaint.setColor(mProgressColor);mBackgroundPaint.setStrokeWidth(mProgressWidth);mBackgroundPaint.setColor(mBackgroundColor);
}复制代码

3. 添加动画

public void setProgress(float progress) {mValueAnimator = ValueAnimator.ofFloat(progress);mValueAnimator.setDuration(1000);mValueAnimator.setInterpolator(new LinearInterpolator());mValueAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {@Overridepublic void onAnimationUpdate(ValueAnimator animation) {mProgress = (float) animation.getAnimatedValue();invalidate();}});mValueAnimator.start();
}复制代码

增加进度监听:

public interface OnProgressChangedListener {void onProgressChanged(float currentProgress);
}复制代码
public void setOnProgressChangedListener(OnProgressChangedListener listener) {mListener = listener;
}复制代码

在布局中增加文字,设置居中:

4. 优化代码

增加静态和动画的区分:

/**
* @param progress      进度
* @param showAnimation 是否展示动画
*/
public void setProgress(float progress, boolean showAnimation) {mShowAnimation = showAnimation;if (mValueAnimator != null && mValueAnimator.isRunning()) {mValueAnimator.cancel();}if (mShowAnimation) {mValueAnimator = ValueAnimator.ofFloat(progress);mValueAnimator.setDuration(mDuration);mValueAnimator.setInterpolator(new LinearInterpolator());mValueAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {@Overridepublic void onAnimationUpdate(ValueAnimator animation) {mProgress = (float) animation.getAnimatedValue();if (mListener != null) {mListener.onProgressChanged(mProgress);}invalidate();}});mValueAnimator.start();} else {mProgress = progress;invalidate();}
}复制代码

设置画笔类型,增加圆头画笔:

public void setCap(Paint.Cap cap) {mProgressPaint.setStrokeCap(cap);mBackgroundPaint.setStrokeCap(cap);
}复制代码

5. 增加切割圆类型

增加进度条类型mProgressType:

/*** 整圆进度条*/
public static final int TYPE_CIRCLE = 0;
/*** 切割圆进度条*/
public static final int TYPE_CLIP = 1;复制代码

切割圆从开始角度到结束角度之间,总进度为100。所以这种情况下:总进度=终止角度 - 起始角度

设置进度的方法修改:

public void setProgress(float progress, boolean showAnimation) {mShowAnimation = showAnimation;if (mProgressType == TYPE_CLIP) {progress = (int) ((mEndAngle - mStartAngle) * 100 / 360.0f);mTotalProgress = progress;} else {mTotalProgress = 100;}if (mValueAnimator != null && mValueAnimator.isRunning()) {mValueAnimator.cancel();}if (mShowAnimation) {mValueAnimator = ValueAnimator.ofFloat(progress);mValueAnimator.setDuration(mDuration);mValueAnimator.setInterpolator(new LinearInterpolator());mValueAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {@Overridepublic void onAnimationUpdate(ValueAnimator animation) {mProgress = (float) animation.getAnimatedValue();if (mListener != null) {mListener.onProgressChanged(mProgress * 100 / mTotalProgress);}invalidate();}});mValueAnimator.start();} else {mProgress = progress;invalidate();}
}复制代码

OnDraw修改,区分切割圆和整圆:

@Override
protected void onDraw(Canvas canvas) {super.onDraw(canvas);mRectf = new RectF(mProgressWidth / 2, mProgressWidth / 2, mViewWidth - mProgressWidth / 2, mViewWidth - mProgressWidth / 2);if (mProgressType == TYPE_CIRCLE) {canvas.drawCircle(mViewWidth / 2, mViewWidth / 2, mViewWidth / 2 - mProgressWidth / 2, mBackgroundPaint);canvas.drawArc(mRectf, mStartAngle, mProgress * 360 / 100, false, mProgressPaint);} else if (mProgressType == TYPE_CLIP) {canvas.drawArc(mRectf, mStartAngle, mEndAngle - mStartAngle, false, mBackgroundPaint);canvas.drawArc(mRectf, mStartAngle, mProgress * 360 / 100, false, mProgressPaint);}
}复制代码

完成。

github地址:https://github.com/opq1289/CircleProgressView

Android自定义圆形进度条相关推荐

  1. android自定义圆形进度条,实现动态画圆效果

    自定义圆形进度条效果图如下:应用场景如动态显示分数等. view的自定义属性如下attr.xml <?xml version="1.0" encoding="UTF ...

  2. Android 自定义圆形进度条(圆环刻度)View

    转载请注明出处http://blog.csdn.net/shallcheek/article/details/50343677 这个也刚好是公司软件最近的需求需要到的,当初最早的版本是使用美工切好的图 ...

  3. android 自定义圆形进度条拖动样式,android自定义圆形进度条

    首先在布局文件定义Progressbar xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tool ...

  4. android绘制环形进度_Android动态自定义圆形进度条

    这篇文章主要介绍了Android动态自定义圆形进度条,需要的朋友可以参考下 效果图: A.绘制圆环,圆弧,文本 //1.画圆环 //原点坐标 float circleX = width / 2; fl ...

  5. android 环形时间显示_Android_Android实现自定义圆形进度条,今天无意中发现一个圆形进度 - phpStudy...

    Android实现自定义圆形进度条 今天无意中发现一个圆形进度,想想自己实现一个,如下图: 基本思路是这样的: 1.首先绘制一个实心圆 2.绘制一个白色实心的正方形,遮住实心圆 3.在圆的中心动态绘制 ...

  6. android自定义进度条百分比跟着走,Android studio圆形进度条 百分数跟随变化

    本文实例为大家分享了Android studio圆形进度条展示的具体代码,供大家参考,具体内容如下 MainActivity import android.support.v7.app.AppComp ...

  7. Android 绘制圆形进度条

    Android 绘制圆形进度条 最近项目上有一些需求,需要绘制圆形的进度条满足设计上和交互上的需求: 实现思路 在画布上直接绘制View,需要了解一下几点 1.需要画一个圆 2.圆圈上有不同进度的颜色 ...

  8. 自定义圆形进度条的实现方式

    如何自定义圆形进度条哪,也就是替换一下进度条的图片而已. 先分析一下,系统对进度条如何定义的: 咱们一般情况下载布局文件中这么书写: //在布局文件里的代码<ProgressBarandroid ...

  9. android 自定义背景园,Android 自定义ProgressBar 进度条颜色和背景颜色

    Android 自定义ProgressBar 进度条颜色和背景颜色 首先,在drawable目录下新建文件 personal_center_level_progress_bg.xmlandroid a ...

最新文章

  1. 人工智能应用于建筑领域新前沿
  2. 星巴克在GitHub中泄漏API密钥,发现者获4000美金奖励
  3. POJ - 3700 Missile Defence System.(dfs+最优性剪枝)
  4. Coding Interview Guide -- 向有序的环形单链表中插入新节点
  5. windowsCE异常和中断服务程序初探(=)
  6. Bootstrap 工具提示插件Tooltip的方法
  7. 「mac操作指南」WidsMob HEIC将HEIC/HEIF 转换为 JPEG/PNG/TIFF格式
  8. HTML5日期输入框(date)
  9. atmega168p与328p_ATMEGA328P-MU产品说明
  10. Tomcat出现中文乱码
  11. 【Windows】替换系统文件
  12. mac 当前位置打开终端
  13. js根据银行卡号进行判断属于哪个银行并返回银行卡类型
  14. 存储服务器在监控中的作用,监控项目中存储服务器IPSAN云存储方案的优劣势对比...
  15. 世界7条高智商测试题
  16. 通关4级之词汇(2021.02.26)
  17. 蓝牙协议spec文档免费下载官网下载(免费)
  18. WPF: WPF 中的 Triggers 和 VisualStateManager
  19. sprite(雪碧图,也叫精灵图)
  20. AT89C51单片机流水灯c语言程序及详解(扫盲教程)

热门文章

  1. MyBatis-08MyBatis注解方式之@Insert
  2. Oracle-内存管理解读
  3. Android Scroll分析
  4. HTML基础_Day02
  5. linux接收网络数据并存存储,linux网络数据包数据结构 Socket Buffer
  6. 导出matlab程序,Matlab数据导入导出
  7. git指定版本openwrt源码_[OpenWrt Wiki] LEDE源代码
  8. native字体尺寸自适应 react_react-native中 屏幕以及字体 大小适配
  9. 系统部署文档_惊喜!Alibaba架构师终于发布“微服务架构与实践”文档
  10. 2021-02-27 永磁同步电机 自抗扰控制 PI调节器 矢量控制 SVPWM