关键词:
最近项目里边要用进度条,进度条中间展示进度,底部展示label,因为这个组件用的地方多,所以我就直接封装了一个通用组件。
先看一下效果图:
功能有:
- 圆环的颜色和进度可以自定义;
- 中间文字可以自定义;
- 可以自定义圆环的宽度;
- 可以设置底部文字(文字内容、大小和textStyle);
- 提供设置进度的接口;
- 可以设置进度的最大值;
下边开始编码:
- 首先继承定义一个类继承自View,因为我们需要提供一些可配置的自定义属性:
public class CircleProgress extends View
private final Paint mPaint; // 画笔
private final RectF mRectF;
private final Rect mRect;
private final Paint mBottomPaint; // 绘制底部文字
private int mCurrent; // 当前进度
private int mMax; // 最大进度
private int mWidth; // 当前view设置的宽度
public CircleProgress(Context context)
this(context,null);
public CircleProgress(Context context, @Nullable AttributeSet attrs)
this(context, attrs,0);
public CircleProgress(Context context, @Nullable AttributeSet attrs, int defStyleAttr)
super(context, attrs, defStyleAttr);
initAttr(context,attrs);
mPaint = new Paint();
mBottomPaint = new Paint();
mBottomPaint.setAntiAlias(true);
mPaint.setAntiAlias(true);
mRectF = new RectF();
mRect = new Rect();
- 自定义属性,在attr.xml中新建一个declare-styleable,并命名为:CircleProgress
<!-- 圆环进度条 -->
<declare-styleable name="CircleProgress">
<attr name="max_progress" format="integer"/>
<attr name="arc_bg_color" format="color"/>
<attr name="arc_color" format="color"/>
<attr name="arc_width" format="dimension"/>
<attr name="mid_text_size" format="dimension"/>
<attr name="bottom_text_size" format="dimension"/>
<attr name="bottom_text" format="string" localization="suggested"/>
<attr name="textStyle">
<flag name="normal" value="0" />
<flag name="bold" value="1" />
</attr>
</declare-styleable>
- 然后我们在initAttr()方法中解析这些属性,解析出来的属性,后边在绘制的时候需要用到:
private void initAttr(Context context, AttributeSet attrs)
TypedArray attributes = context.obtainStyledAttributes(attrs,R.styleable.CircleProgress);
mMax = attributes.getInteger(R.styleable.CircleProgress_max_progress, 100);
mCircleBGColor = attributes.getColor(R.styleable.CircleProgress_arc_bg_color,context.getResources().getColor(R.color.color_d1, null));
mCircleColor = attributes.getColor(R.styleable.CircleProgress_arc_color,context.getResources().getColor(R.color.colorRed, null));
mArcWidth = attributes.getDimensionPixelOffset(R.styleable.CircleProgress_arc_width,SizeUtils.dp2px(20));
mPercentTextSize = attributes.getDimensionPixelOffset(R.styleable.CircleProgress_mid_text_size,SizeUtils.sp2px(12));
mBottomTextSize = attributes.getDimensionPixelOffset(R.styleable.CircleProgress_bottom_text_size,SizeUtils.sp2px(14));
mBottomTextId = attributes.getResourceId(R.styleable.CircleProgress_bottom_text,0);
mBottomText = attributes.getText(R.styleable.CircleProgress_bottom_text).toString();
mBottomTextType = attributes.getInt(R.styleable.CircleProgress_textStyle,0);
attributes.recycle();
- 解析完属性之后,就可以开始绘制了,绘制主要按照顺序绘制,我们先绘制圆环,在绘制百分比,然后绘制底部文字:
@Override
protected void onDraw(Canvas canvas)
super.onDraw(canvas);
//绘制圆形
//设置为空心圆,如果不理解绘制弧线是什么意思就把这里的属性改为“填充”,跑一下瞬间就明白了
mPaint.setStyle(Paint.Style.STROKE);
mPaint.setAntiAlias(true);
//设置圆弧的宽度(圆环的宽度)
mPaint.setStrokeWidth(mArcWidth);
mPaint.setColor(mCircleBGColor);
//大圆的半径
float bigCircleRadius = mWidth / 2;
// 小圆的半径
float smallCircleRadius = bigCircleRadius - mArcWidth;
// 绘制小圆
canvas.drawCircle(bigCircleRadius,bigCircleRadius,smallCircleRadius,mPaint);
mPaint.setColor(mCircleColor);
mRectF.set(mArcWidth,mArcWidth,mWidth - mArcWidth,mWidth - mArcWidth);
// 绘制圆弧
canvas.drawArc(mRectF,90f,mCurrent * 360f / mMax, false, mPaint);
// 计算百分比
String percent = mCurrent * 100 / mMax + "%";
mPaint.setStrokeWidth(0);
mPaint.setStyle(Paint.Style.FILL);
mPaint.setTextSize(mPercentTextSize);
mPaint.getTextBounds(percent, 0, percent.length(), mRect);
mPaint.setColor(mCircleColor);
// 绘制百分比
canvas.drawText(percent,bigCircleRadius- mRect.width() / 2, bigCircleRadius + mRect.height() / 2, mPaint);
// 绘制底部文字
if (!TextUtils.isEmpty(mBottomText))
mBottomPaint.setStrokeWidth(0);
mBottomPaint.setTextSize(mBottomTextSize);
mBottomPaint.getTextBounds(mBottomText.toString(),0, mBottomText.toString().length(),mRect);
mBottomPaint.setColor(Color.BLACK);
if (mBottomTextType == 1)
Typeface tf = Typeface.DEFAULT_BOLD;
mBottomPaint.setTypeface(tf);
canvas.drawText(mBottomText.toString(),bigCircleRadius - mRect.width() / 2f, mWidth + mRect.height(), mBottomPaint);
else if(mBottomTextId > 0)
String bottomText = getResources().getString(mBottomTextId);
mBottomPaint.setStrokeWidth(0);
mBottomPaint.setTextSize(mBottomTextSize);
mBottomPaint.getTextBounds(bottomText,0, bottomText.length(),mRect);
mBottomPaint.setColor(Color.BLACK);
if (mBottomTextType == 1)
Typeface tf = Typeface.DEFAULT_BOLD;
mBottomPaint.setTypeface(tf);
canvas.drawText(bottomText,bigCircleRadius - mRect.width() / 2f, mWidth + mRect.height(), mBottomPaint);
- 编译之后就可以在布局文件中使用了:
<com.towngas.top.commonlibrary.widget.CircleProgress
android:id="@+id/cp_timeliness_patrol"
android:layout_width="0dp"
android:layout_weight="1"
android:layout_height="match_parent"
app:max_progress="100"
app:arc_width="@dimen/dp_12"
app:arc_bg_color="#FBCCA0"
app:arc_color="#FBCCA0"
app:bottom_text_size="@dimen/sp_14"
app:textStyle="bold"
app:bottom_text="下载"/>
完整代码:
public class CircleProgress extends View
private final Paint mPaint; // 画笔
private final RectF mRectF;
private final Rect mRect;
private final Paint mBottomPaint; // 绘制底部文字
private int mCurrent; // 当前进度
private int mMax; // 最大进度
private int mWidth; // 当前view设置的宽度
//圆弧(也可以说是圆环)的宽度
private float mArcWidth;
private int mCircleBGColor; // 自定义圆环背景color
private int mCircleColor; // 自定义圆环clolr
private int mBottomTextId = Resources.ID_NULL; // 底部文字
private CharSequence mBottomText; //底部文字
private float mPercentTextSize; // 百分比文字大小
private float mBottomTextSize; // 底部文字大小
private int mBottomTextType; // 字体样式
public CircleProgress(Context context)
this(context,null);
public CircleProgress(Context context, @Nullable AttributeSet attrs)
this(context, attrs,0);
public CircleProgress(Context context, @Nullable AttributeSet attrs, int defStyleAttr)
super(context, attrs, defStyleAttr);
initAttr(context,attrs);
mPaint = new Paint();
mBottomPaint = new Paint();
mBottomPaint.setAntiAlias(true);
mPaint.setAntiAlias(true);
mRectF = new RectF();
mRect = new Rect();
private void initAttr(Context context, AttributeSet attrs)
TypedArray attributes = context.obtainStyledAttributes(attrs,R.styleable.CircleProgress);
mMax = attributes.getInteger(R.styleable.CircleProgress_max_progress, 100);
mCircleBGColor = attributes.getColor(R.styleable.CircleProgress_arc_bg_color,context.getResources().getColor(R.color.color_d1, null));
mCircleColor = attributes.getColor(R.styleable.CircleProgress_arc_color,context.getResources().getColor(R.color.colorRed, null));
mArcWidth = attributes.getDimensionPixelOffset(R.styleable.CircleProgress_arc_width,SizeUtils.dp2px(20));
mPercentTextSize = attributes.getDimensionPixelOffset(R.styleable.CircleProgress_mid_text_size,SizeUtils.sp2px(12));
mBottomTextSize = attributes.getDimensionPixelOffset(R.styleable.CircleProgress_bottom_text_size,SizeUtils.sp2px(14));
mBottomTextId = attributes.getResourceId(R.styleable.CircleProgress_bottom_text,0);
mBottomText = attributes.getText(R.styleable.CircleProgress_bottom_text).toString();
mBottomTextType = attributes.getInt(R.styleable.CircleProgress_textStyle,0);
attributes.recycle();
/**
* 设置当前进度
* @param current
*/
public void SetCurrent(int current)
this.mCurrent = current;
invalidate();
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec)
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
//getMeasuredWidth获取的是view的原始大小,也就是xml中配置或者代码中设置的大小
//getWidth获取的是view最终显示的大小,这个大小不一定等于原始大小
mWidth = getMeasuredWidth();
@Override
protected void onDraw(Canvas canvas)
super.onDraw(canvas);
//绘制圆形
//设置为空心圆,如果不理解绘制弧线是什么意思就把这里的属性改为“填充”,跑一下瞬间就明白了
mPaint.setStyle(Paint.Style.STROKE);
mPaint.setAntiAlias(true);
//设置圆弧的宽度(圆环的宽度)
mPaint.setStrokeWidth(mArcWidth);
mPaint.setColor(mCircleBGColor);
//大圆的半径
float bigCircleRadius = mWidth / 2;
// 小圆的半径
float smallCircleRadius = bigCircleRadius - mArcWidth;
// 绘制小圆
canvas.drawCircle(bigCircleRadius,bigCircleRadius,smallCircleRadius,mPaint);
mPaint.setColor(mCircleColor);
mRectF.set(mArcWidth,mArcWidth,mWidth - mArcWidth,mWidth - mArcWidth);
// 绘制圆弧
canvas.drawArc(mRectF,90f,mCurrent * 360f / mMax, false, mPaint);
// 计算百分比
String percent = mCurrent * 100 / mMax + "%";
mPaint.setStrokeWidth(0);
mPaint.setStyle(Paint.Style.FILL);
mPaint.setTextSize(mPercentTextSize);
mPaint.getTextBounds(percent, 0, percent.length(), mRect);
mPaint.setColor(mCircleColor);
// 绘制百分比
canvqt编写自定义控件14-环形进度条(代码片段)
前言环形进度条,用来展示当前进度,为了满足大屏UI的需要特意定制,以前有个叫圆环进度条,不能满足项目需要,只能重新定做,以前的进度间距不能自适应分辨率,而且当前进度对应的反的进度不能单独设置颜色,即当前... 查看详情
酷炫进度条自定义seekbar(代码片段)
前些天一同学给了我一个ui图,是这样子的:需求:1、看了ui图可以知道这类似android自带的seekbar控件,2、一个水平进度条和一个圆形进度条;3、圆形进度条显示环形刻度和当前进度值;4、并且圆形进度... 查看详情
一起talkandroid吧(第四百九十六回:自定义view实例二:环形进度条)
...是"如何使用Java版MQTT客户端",这一回中咱们说的例子是"自定义View实例二:环形进度条"。闲话休提,言归正转,让我们一起TalkAndroid吧!知识回顾看官们,我们又回到了自定义View相关的知识中,在这里对旧知识做一些回顾:首先... 查看详情
echarts实现环形进度条(代码片段)
效果图实现代码可直接复制运行:<!DOCTYPEhtml><html> <head> <metacharset="UTF-8"> <title>环形进度条</title> <scriptsrc="https://cdn.staticfile.org/echart 查看详情
compose自定义条形进度条(代码片段)
前言Compose自定义View其实比View系统更方便简单,比如接下来本文要介绍的就是使用Compose实现View系统中常见的条形进度条。自定义进度条Composematerial包中提供了CircularProgressIndicator实现View系统中的圆形进度条,因为Compose没... 查看详情
compose自定义条形进度条(代码片段)
前言Compose自定义View其实比View系统更方便简单,比如接下来本文要介绍的就是使用Compose实现View系统中常见的条形进度条。自定义进度条Composematerial包中提供了CircularProgressIndicator实现View系统中的圆形进度条,因为Compose没... 查看详情
用svg实现一个环形进度条(代码片段)
svg实现环形进度条需要用到的知识:1、会使用path的d属性画一个圆环2、熟悉stroke,stroke-linecap,stroke-width,stroke-dasharray、stroke-dashoffset 话不多说,直接上代码<divstyle="width:200px;height:200px;"><svgviewBox="00100100">&l 查看详情
图解css3制作圆环形进度条的实例教程
圆环形进度条制作的基本思想还是画出基本的弧线图形,然后CSS3中我们可以控制其旋转来串联基本图形,制造出部分消失的效果,下面就来带大家学习图解CSS3制作圆环形进度条的实例教程首先,当有人说你能不能做一个圆形进度条... 查看详情
compose自定义条形进度条(代码片段)
前言Compose自定义View其实比View系统更方便简单,比如接下来本文要介绍的就是使用Compose实现View系统中常见的条形进度条。自定义进度条Composematerial包中提供了CircularProgressIndicator实现View系统中的圆形进度条,因为Compose没... 查看详情
用初中数学知识撸一个canvas环形进度条(代码片段)
周末好,今天给大家带来一款接地气的环形进度条组件vue-awesome-progress。近日被设计小姐姐要求实现这么一个环形进度条效果,大体由四部分组成,分别是底色圆环,进度弧,环内文字,进度圆点。设计稿截图如下:我的第一反... 查看详情
android自定义圆弧进度条(代码片段)
...到合适,干脆就自己写了一个,顺便复习一下自定义View,下面是具体的实现。先看一下效果这里的话我只做一个进度条 查看详情
csssvg环形进度条-5(代码片段)
htmlsvg环形进度条-7(代码片段)
csssvg环形进度条-3。(代码片段)
htmlsvg环形进度条-4(代码片段)
htmlsvg环形进度条-2(代码片段)
htmlsvg环形进度条-1(代码片段)
仿字节颜色自定义android进度条(代码片段)
效果展示代码实现第一步:编写自定义属性 res/values/attrs.xml<?xmlversion="1.0"encoding="utf-8"?><resources><declare-styleablename="MyLoadingView"><attrname="loading_color_one"format="color"/> 查看详情