首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> C語言 >> C++ >> C++ 入門

Android 自定義圓環進度條 CircleProgress:屬性動畫與 Canvas 繪製

     編輯:C++ 入門

效果預覽

圓環進度條,支持設置百分比(0-100),中心顯示文本,外圍圓環按比例繪製掃描角度。效果圖:

CircleProgress 效果圖

核心實現

  1. onMeasure:取寬高較小值作為直徑,計算圓心 (cx,cy)、半徑、矩形區域 RectF。
  2. onDraw:
    ① 繪製背景圓 drawCircle(可選)。
    ② 繪製前景圓弧 drawArc,startAngle=270(12點鐘方向),sweepAngle = percent * 3.6。
    ③ 繪製中心文本 drawText,基線微調 cy + textSize/4 垂直居中。
  3. 屬性設置:setSweepValue(float percent) 觸發 invalidate() 重繪。

完整代碼(Kotlin/Java)

public class CircleProgress extends View {
    private Paint circlePaint, arcPaint, textPaint;
    private RectF arcRect;
    private float cx, cy, radius, strokeWidth;
    private float sweepValue = 0f;  // 0-100
    private String showText = "";
    private float textSize = 40f;

    public CircleProgress(Context context, AttributeSet attrs) {
        super(context, attrs);
        init();
    }

    private void init() {
        circlePaint = new Paint(Paint.ANTI_ALIAS_FLAG);
        circlePaint.setColor(Color.BLUE);
        circlePaint.setStyle(Paint.Style.STROKE);
        circlePaint.setStrokeWidth(20f);

        arcPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
        arcPaint.setColor(Color.RED);
        arcPaint.setStyle(Paint.Style.STROKE);
        arcPaint.setStrokeWidth(20f);
        arcPaint.setStrokeCap(Paint.Cap.ROUND);

        textPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
        textPaint.setColor(Color.BLACK);
        textPaint.setTextSize(textSize);
        textPaint.setTextAlign(Paint.Align.CENTER);
    }

    @Override protected void onMeasure(int wSpec, int hSpec) {
        int w = MeasureSpec.getSize(wSpec);
        int h = MeasureSpec.getSize(hSpec);
        int d = Math.min(w, h);
        setMeasuredDimension(d, d);
        cx = cy = d / 2f;
        radius = d * 0.35f;
        strokeWidth = d * 0.1f;
        circlePaint.setStrokeWidth(strokeWidth);
        arcPaint.setStrokeWidth(strokeWidth);
        float inset = strokeWidth / 2f;
        arcRect = new RectF(inset, inset, d - inset, d - inset);
        textSize = d * 0.25f;
        textPaint.setTextSize(textSize);
    }

    @Override protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        // 背景圓(可選)
        // canvas.drawCircle(cx, cy, radius, circlePaint);
        // 前景弧
        float sweepAngle = sweepValue * 3.6f;  // 100% = 360°
        canvas.drawArc(arcRect, 270, sweepAngle, false, arcPaint);
        // 中心文本
        canvas.drawText(showText, cx, cy + textSize / 3f, textPaint);
    }

    public void setSweepValue(float value) {
        sweepValue = Math.max(0, Math.min(100, value));
        showText = String.format("%.0f%%", sweepValue);
        invalidate();
    }

    public void setShowText(String text) {
        showText = text;
        invalidate();
    }
}

XML 使用示例

<com.example.CircleProgress
    android:id="@+id/progress"
    android:layout_width="200dp"
    android:layout_height="200dp" />

代碼調用

CircleProgress cp = findViewById(R.id.progress);
cp.setSweepValue(75f);  // 顯示 75%

關鍵點總結

  • 抗鋸齒:Paint.ANTI_ALIAS_FLAG 邊緣平滑。
  • 圓弧方向:startAngle=270 從頂部開始,順時針。
  • 文本垂直居中:cy + textSize/3 經驗補正(Paint 基線在字符底部)。
  • 線帽樣式:Paint.Cap.ROUND 使弧端點圓潤。
  • 性能:僅 invalidate() 觸發重繪,無動畫時極輕量。
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved