Android花樣loading進度條(三)-配文字環形進度條

coyan發表於2021-09-09

一文中有講解過。


2、繪製文字
由於本篇在上一篇簡單環形進度上加了文字,有一些基礎部分重合了,本篇主要講差異化的部分,即繪製文字部分。
// step3 畫文字指示
paint.setStrokeWidth(0);
paint.setColor(textColor);
paint.setTextSize(textSize);
// 計算百分比
int percent = (int) (((float) progress / (float) max) * 100);

if (textShow && text != null && text.length() > 0 && percent >= 0) {
    // 3.1 畫文字
    paint.setTypeface(Typeface.DEFAULT); // 設定為預設字型
    float textWidth = paint.measureText(text); // 測量字型寬度
    canvas.drawText(text, centerX - textWidth / 2, centerX + textSize + 5, paint);
    // 3.2 畫百分比
    paint.setTextSize(numSize);
    if (useCustomFont) {
        paint.setTypeface(AppResource.getTypeface(getContext())); // 設定字型
    } else {
        paint.setTypeface(Typeface.DEFAULT_BOLD); // 設定為加粗預設字型
    }
    float numWidth = paint.measureText(percent + "%"); // 測量字型寬度,我們需要根據字型的寬度設定在圓環中間
    canvas.drawText(percent + "%", centerX - numWidth / 2, centerX, paint); // 畫出進度百分比
}

作解釋如下:

  • percent:進度值對應的百分比,比較好理解;

  • textWidth:使用畫筆測量出的文字寬度;

  • centerX 表示控制元件中心x座標,centerX - textWidth / 2表示的點在中心向左偏移字型一半的長度;

  • drawText方法引數x=(centerX - textWidth / 2)表示文字要橫向居中;

  • drawText方法引數y=(centerX + textSize + 5)表示文字豎向位置,由於這裡不是垂直居中的,就是靠引數調出來的效果,不具有普及型;

  • paint.setTypeface:本方法可以設定畫筆使用的文字字型。

至此,進度條繪製就完成了,整個TextRoundProgress的程式碼為:

package com.dommy.loading.widget;

import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.RectF;
import android.graphics.Typeface;
import android.util.AttributeSet;
import android.view.View;

import com.dommy.loading.R;
import com.dommy.loading.util.AppResource;

/**
 * 配文字環形進度條
 */
public class TextRoundProgress extends View {
    private Paint paint; // 畫筆物件的引用
    private int roundColor; // 圓環的顏色
    private float roundWidth; // 圓環的寬度
    private int progressColor; // 圓環進度的顏色
    private float progressWidth; // 圓環進度的寬度
    private String text; // 文字內容
    private int textColor; // 中間進度百分比的字串的顏色
    private float textSize; // 中間進度百分比的字串的字型大小
    private float numSize; // 中間進度文字大小
    private int max; // 最大進度
    private int startAngle; // 進度條起始角度
    private boolean textShow; // 是否顯示中間的進度
    private boolean useCustomFont; // 是否使用自定義字型
    private int progress; // 當前進度

    public TextRoundProgress(Context context) {
        this(context, null);
    }

    public TextRoundProgress(Context context, AttributeSet attrs) {
        this(context, attrs, 0);
    }

    public TextRoundProgress(Context context, AttributeSet attrs, int defStyle) {
        super(context, attrs, defStyle);

        paint = new Paint();

        // 讀取自定義屬性的值
        TypedArray mTypedArray = context.obtainStyledAttributes(attrs, R.styleable.TextRoundProgress);

        // 獲取自定義屬性和預設值
        roundColor = mTypedArray.getColor(R.styleable.TextRoundProgress_trp_roundColor, Color.RED);
        roundWidth = mTypedArray.getDimension(R.styleable.TextRoundProgress_trp_roundWidth, 5);
        progressColor = mTypedArray.getColor(R.styleable.TextRoundProgress_trp_progressColor, Color.GREEN);
        progressWidth = mTypedArray.getDimension(R.styleable.TextRoundProgress_trp_progressWidth, roundWidth);
        text = mTypedArray.getString(R.styleable.TextRoundProgress_trp_text);
        textColor = mTypedArray.getColor(R.styleable.TextRoundProgress_trp_textColor, Color.GREEN);
        textSize = mTypedArray.getDimension(R.styleable.TextRoundProgress_trp_textSize, 11);
        numSize = mTypedArray.getDimension(R.styleable.TextRoundProgress_trp_numSize, 14);
        max = mTypedArray.getInteger(R.styleable.TextRoundProgress_trp_max, 100);
        startAngle = mTypedArray.getInt(R.styleable.TextRoundProgress_trp_startAngle, 90);
        textShow = mTypedArray.getBoolean(R.styleable.TextRoundProgress_trp_textShow, true);
        useCustomFont = mTypedArray.getBoolean(R.styleable.TextRoundProgress_trp_userCustomFont, false);
        mTypedArray.recycle();
    }

    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);

        int centerX = getWidth() / 2; // 獲取圓心的x座標
        int radius = (int) (centerX - roundWidth / 2); // 圓環的半徑

        // step1 畫最外層的大圓環
        paint.setStrokeWidth(roundWidth); // 設定圓環的寬度
        paint.setColor(roundColor); // 設定圓環的顏色
        paint.setAntiAlias(true); // 消除鋸齒
        // 設定畫筆樣式
        paint.setStyle(Paint.Style.STROKE);
        canvas.drawCircle(centerX, centerX, radius, paint); // 畫出圓環

        // step2 畫圓弧-畫圓環的進度
        paint.setStrokeWidth(progressWidth); // 設定畫筆的寬度使用進度條的寬度
        paint.setColor(progressColor); // 設定進度的顏色
        RectF oval = new RectF(centerX - radius, centerX - radius, centerX + radius, centerX + radius); // 用於定義的圓弧的形狀和大小的界限

        int sweepAngle = 360 * progress / max; // 計算進度值在圓環所佔的角度
        // 根據進度畫圓弧
        canvas.drawArc(oval, startAngle, sweepAngle, false, paint);

        // step3 畫文字指示
        paint.setStrokeWidth(0);
        paint.setColor(textColor);
        paint.setTextSize(textSize);
        // 計算百分比
        int percent = (int) (((float) progress / (float) max) * 100);

        if (textShow && text != null && text.length() > 0 && percent >= 0) {
            // 3.1 畫文字
            paint.setTypeface(Typeface.DEFAULT); // 設定為預設字型
            float textWidth = paint.measureText(text); // 測量字型寬度
            canvas.drawText(text, centerX - textWidth / 2, centerX + textSize + 5, paint);
            // 3.2 畫百分比
            paint.setTextSize(numSize);
            if (useCustomFont) {
                paint.setTypeface(AppResource.getTypeface(getContext())); // 設定字型
            } else {
                paint.setTypeface(Typeface.DEFAULT_BOLD); // 設定為加粗預設字型
            }
            float numWidth = paint.measureText(percent + "%"); // 測量字型寬度,我們需要根據字型的寬度設定在圓環中間
            canvas.drawText(percent + "%", centerX - numWidth / 2, centerX, paint); // 畫出進度百分比
        }
    }

    /**
     * 設定進度的最大值
     * 

根據需要,最大值一般設定為100,也可以設定為1000、10000等

     *      * @param max int最大值      */     public synchronized void setMax(int max) {         if (max  max) {             progress = max;         }         this.progress = progress;         // 重新整理介面呼叫postInvalidate()能在非UI執行緒重新整理         postInvalidate();     } }


來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/2236/viewspace-2800601/,如需轉載,請註明出處,否則將追究法律責任。

相關文章