先看效果:
首先是自定义属性:
自定义控件:
最后是使用看看:
```java
public class HalfCircleextends View {
/**
* 底层半圆颜色
*/
private int bg_color;
/**
* 上层进度半圆颜色
*/
private int fore_color;
/**
* 半径
*/
private int radius_len;
/**
* 文字内容
*/
private Stringstr_text;
/**
* mPaint 底层画笔,mTextPaint文字画笔,mForePaint上层半圆画笔
*/
private PaintmPaint,mTextPaint,mForePaint;
/**
* 进度条的宽度
*/
private int strokeWidth=40;
/**
* 进度
*/
private float progress=0;
/**
* 文字大小
*/
private int txt_size;
public HalfCircle(Context context) {
this(context,null);
}
public HalfCircle(Context context, @Nullable AttributeSet attrs) {
this(context, attrs,0);
}
/**
* 获取控件属性,并初始化画笔
* @param context
* @param attrs
* @param defStyleAttr
*/
public HalfCircle(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
TypedArray array=context.obtainStyledAttributes(attrs,R.styleable.Half_Circle_attrs);
bg_color=array.getColor(R.styleable.Half_Circle_attrs_bg_color,bg_color);
fore_color=array.getColor(R.styleable.Half_Circle_attrs_fore_color,fore_color);
radius_len= (int) array.getDimension(R.styleable.Half_Circle_attrs_radius_len,radius_len);
str_text= (String) array.getText(R.styleable.Half_Circle_attrs_text_str);
txt_size= (int) array.getDimension(R.styleable.Half_Circle_attrs_txt_size,txt_size);
array.recycle();
mPaint=new Paint();//初始化画笔
mPaint.setAntiAlias(true);//抗锯齿
mPaint.setColor(bg_color);//设置底层颜色
mPaint.setStrokeWidth(strokeWidth);//画笔描边宽度
mPaint.setStrokeCap(Paint.Cap.ROUND);//设置画笔两端为半圆
mPaint.setTextSize(txt_size);//设置字体大小
mPaint.setStyle(Paint.Style.STROKE);//设置绘制区域style为镂空,另一种是fill,即填充
mTextPaint=new Paint();//文字画笔
mTextPaint.setTextSize(txt_size);
mForePaint=new Paint();//同底层画笔,不赘述
mForePaint.setAntiAlias(true);
mForePaint.setColor(fore_color);
mForePaint.setStrokeWidth(strokeWidth);
mForePaint.setStrokeCap(Paint.Cap.ROUND);
mForePaint.setTextSize(txt_size);
mForePaint.setStyle(Paint.Style.STROKE);
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
int widthSize=MeasureSpec.getSize(widthMeasureSpec);
int widthMode=MeasureSpec.getMode(widthMeasureSpec);
int heightSize=MeasureSpec.getSize(heightMeasureSpec);
int heightMode=MeasureSpec.getMode(heightMeasureSpec);
Rect mRect=new Rect();
//从画笔中获取文字长度及大小的Rect,这时rect包含了我们需要的文字长度等信息
mPaint.getTextBounds(str_text,0,str_text.length(),mRect);
if(widthMode==MeasureSpec.AT_MOST){//当控件是wrap_content时,计算控件的宽度
//控件的总体宽度是文字宽度的一半+直径+左右padding.之所以加上文字宽度是为了在文字变化时,控件的大小也随之改变
widthSize=mRect.width()/2+radius_len*2+getPaddingLeft()+getPaddingRight();
}
if(heightMode==MeasureSpec.AT_MOST){
//控件的总体宽度是文字宽度的一半+直径+上下padding。同上
heightSize=mRect.width()/2+radius_len*2+getPaddingTop()+getPaddingBottom();
}
//最后设置宽高
setMeasuredDimension(widthSize,heightSize);
}
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
/**
* rectF的绘制宽高应该去除两倍的strokeWidth,否则弧度绘制不全
*/
RectF rectF=new RectF(strokeWidth,strokeWidth,getWidth()-strokeWidth*2,getHeight()-strokeWidth*2);
//绘制灰色底层圆弧
canvas.drawArc(rectF,135,270,false,mPaint);
//根据进度绘制第二层圆弧
canvas.drawArc(rectF,135,270*progress,false,mForePaint);
int y= (int) (getHeight()/2+(mTextPaint.descent()-mTextPaint.ascent())/2-mTextPaint.descent())-strokeWidth;
int x= (int) ((getWidth()-strokeWidth)/2-mTextPaint.measureText(str_text)/2);
canvas.drawText(str_text,x,y,mTextPaint);
}
/**
*
* @param prog 设置进度并重绘
*/
public void setProgress(Float prog){
progress=prog;
invalidate();
}
}
```