Android 從 0 開始學(xué)習(xí)自定義 View(二) 自定義圓弧

1.自定義 View 的基本流程

  • 創(chuàng)建 View Class
  • 創(chuàng)建 attr 屬性文件,確定屬性
  • View Class 綁定 attr 屬性
  • onMeasure 測量
  • onDraw 繪制
1.1 創(chuàng)建 View Class
public class ArcView extends View {
    public ArcView(Context context) {
        this(context, null);
    }
    public ArcView(Context context, @Nullable AttributeSet attrs) {
        this(context, attrs, 0);
    }
    public ArcView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
    }
}
1.2 創(chuàng)建 attr 屬性
<declare-styleable name="ArcView">
    <!--內(nèi)環(huán)顏色-->
    <attr name="arcInnerColor" format="color" />
    <!--外環(huán)顏色-->
    <attr name="arcOutColor" format="color" />
    <!--環(huán)大小-->
    <attr name="arcWidth" format="dimension" />
    <!--文字-->
    <attr name="arcText" format="string" />
     <!--文字大小-->
    <attr name="arcTextSize" format="dimension" />
    <!--文字顏色-->
    <attr name="arcTextColor" format="color" />
</declare-styleable>
1.3 綁定屬性
private void initAttr(Context context, AttributeSet attrs) {
    TypedArray array = context.obtainStyledAttributes(attrs, R.styleable.ArcView);
    //外環(huán)顏色
    mInnerColor = array.getColor(R.styleable.ArcView_arcInnerColor, mInnerColor);
    //內(nèi)環(huán)顏色
    mOutColor = array.getColor(R.styleable.ArcView_arcOutColor, mOutColor);
    //環(huán)大小
    mWidth = (int) array.getDimension(R.styleable.ArcView_arcWidth, mWidth);
    //文字
    mText = array.getString(R.styleable.ArcView_arcText);
    //文字大小
    mTextSize = array.getDimensionPixelSize(R.styleable.ArcView_arcTextSize, mTextSize);
    //文字顏色
    mTextColor = array.getColor(R.styleable.ArcView_arcTextColor, mTextColor);
    array.recycle();
}
1.4 onMeasure
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
    super.onMeasure(widthMeasureSpec, heightMeasureSpec);
    //確保正方形,將短邊的大小設(shè)為狂傲
    //寬
    int width = MeasureSpec.getSize(widthMeasureSpec);
    //高
    int height = MeasureSpec.getSize(heightMeasureSpec);
    //設(shè)置寬高
    setMeasuredDimension(Math.min(width, height), Math.min(width, height));
}
1.5 onDraw
protected void onDraw(Canvas canvas) {
    super.onDraw(canvas);
}
  • 第一步,畫內(nèi)環(huán)
private void initInnerPaint() {
    mInnerPaint = new Paint();
    //抗鋸齒
    mInnerPaint.setAntiAlias(true);
    //防抖動
    mInnerPaint.setDither(true);
    //寬度
    mInnerPaint.setStrokeWidth(mWidth);
    //顏色
    mInnerPaint.setColor(mInnerColor);
    //設(shè)置狀態(tài)
    mInnerPaint.setStyle(Paint.Style.STROKE);
    //頭部小圓點
    mInnerPaint.setStrokeCap(Paint.Cap.ROUND);
}
protected void onDraw(Canvas canvas) {
    super.onDraw(canvas);
    //畫內(nèi)環(huán)
    RectF rectF = new RectF(mWidth / 2, mWidth / 2, getWidth() - mWidth / 2, getHeight() - mWidth / 2);
    canvas.drawArc(rectF, 135, 270, false, mInnerPaint);
}
內(nèi)環(huán)
  • 第二步,畫外環(huán)
private void initOutPaint() {
    mOutPaint = new Paint();
    //抗鋸齒
    mOutPaint.setAntiAlias(true);
    //防抖動
    mOutPaint.setDither(true);
    //寬度
    mOutPaint.setStrokeWidth(mWidth);
    //顏色
    mOutPaint.setColor(mOutColor);
    //設(shè)置狀態(tài)
    mOutPaint.setStyle(Paint.Style.STROKE);
    //頭部小圓點
    mOutPaint.setStrokeCap(Paint.Cap.ROUND);
}
protected void onDraw(Canvas canvas) {
    super.onDraw(canvas);
    //畫內(nèi)環(huán)
    RectF rectF = new RectF(mWidth / 2, mWidth / 2, getWidth() - mWidth / 2, getHeight() - mWidth / 2);
    canvas.drawArc(rectF, 135, 270, false, mInnerPaint);
    //畫內(nèi)環(huán)
    if (MaxProgress == 0) return;
    float sweepAngle = (float) CurrentProgress / MaxProgress;
    canvas.drawArc(rectF, 135, sweepAngle * 270, false, mOutPaint);
}
外環(huán)
  • 第三步,畫文字
private void initTextPaint() {
    mTextPaint = new Paint();
    //抗鋸齒
    mTextPaint.setAntiAlias(true);
    //文字大小
    mTextPaint.setTextSize(mTextSize);
    //文字顏色
    mTextPaint.setColor(mTextColor);
}
protected void onDraw(Canvas canvas) {
    super.onDraw(canvas);
    //畫內(nèi)環(huán)
    RectF rectF = new RectF(mWidth / 2, mWidth / 2, getWidth() - mWidth / 2, getHeight() - mWidth / 2);
    canvas.drawArc(rectF, 135, 270, false, mInnerPaint);
    //畫內(nèi)環(huán)
    if (MaxProgress == 0) return;
    float sweepAngle = (float) CurrentProgress / MaxProgress;
    canvas.drawArc(rectF, 135, sweepAngle * 270, false, mOutPaint);
    //畫文字
    //測量文字寬度
    Rect rect = new Rect();
    mTextPaint.getTextBounds(mText, 0, mText.length(), rect);
    int x = getWidth() / 2 - rect.width() / 2;
    //基線
    Paint.FontMetricsInt fontMetricsInt = mTextPaint.getFontMetricsInt();
    int y = (fontMetricsInt.bottom - fontMetricsInt.top) / 2 - fontMetricsInt.bottom;
    int baseline = getHeight() / 2 + y;
    canvas.drawText(mText, x, baseline, mTextPaint);
}
最終效果圖
自定義圓弧就介紹到這里了,如果有什么寫得不對的,可以在下方評論留言,我會第一時間改正。

Github 源碼鏈接

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容