先看效果:
首先是自定義屬性:
自定義控件:
最后是使用看看:
? ??????```java
public class HalfCircleextends View {
/**
? ? * 底層半圓顏色
? ? */
? ? private int bg_color;
? ? /**
? ? * 上層進度半圓顏色
? ? */
? ? private int fore_color;
? ? /**
? ? * 半徑
? ? */
? ? private int radius_len;
? ? /**
? ? * 文字內(nèi)容
? ? */
? ? 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);//設(shè)置底層顏色
? ? ? ? mPaint.setStrokeWidth(strokeWidth);//畫筆描邊寬度
? ? ? ? mPaint.setStrokeCap(Paint.Cap.ROUND);//設(shè)置畫筆兩端為半圓
? ? ? ? mPaint.setTextSize(txt_size);//設(shè)置字體大小
? ? ? ? mPaint.setStyle(Paint.Style.STROKE);//設(shè)置繪制區(qū)域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){//當(dāng)控件是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();
? ? ? ? }
//最后設(shè)置寬高
? ? ? ? setMeasuredDimension(widthSize,heightSize);
? ? }
@Override
? ? protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
? ? ? ? /**
? ? ? ? * rectF的繪制寬高應(yīng)該去除兩倍的strokeWidth,否則弧度繪制不全
? ? ? ? */
? ? ? ? RectF rectF=new RectF(strokeWidth,strokeWidth,getWidth()-strokeWidth*2,getHeight()-strokeWidth*2);
? ? ? ? //繪制灰色底層圓弧
? ? ? ? canvas.drawArc(rectF,135,270,false,mPaint);
? ? ? ? //根據(jù)進度繪制第二層圓弧
? ? ? ? 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 設(shè)置進度并重繪
? ? */
? ? public void setProgress(Float prog){
progress=prog;
? ? ? ? invalidate();
? ? }
}
? ??????```