1. 程式人生 > >Android開發:Android自定義View

Android開發:Android自定義View

本文為博主- 山水相逢-z  原創文章,地址: https://blog.csdn.net/weixin_38251977/article/details/82286127

上週遇到一個需求,用一個圓形進度條的形式來展示某項操作所佔的比例,雖然類似的輪子已經有很多了,但是這種簡單的自定義View個人覺得有時間的話,還是自己寫寫比較好。

首先來看一下效果圖: 實現效果圖

分析:  從效果圖可以看到,這個效果整體分為以下幾部分:

  • 背景圓環
  • 進度圓弧
  • 終點小圓圈(進度為0和進度為100%的時候應當沒有)
  • 內部三行文字

怎麼實現:  分析出整體框架之後,思路其實已經很簡單了,我是這樣實現的:

  1. 畫背景圓
  2. 按照當前進度計算出掃過的弧度來畫一個圓弧
  3. 以第二步的圓弧結束位置為座標,畫兩個大小不同的實心圓,達到設計效果
  4. 分別畫三行文字

第三步中,在確定圓弧終點位置的時候用到了三角函式,這裡簡單畫了一個圖,很好理解: 三角函式計算圓弧終點位置座標

以頂點為起點,圓半徑為r,圓弧掃過的角度為α。

程式碼  簡單列下主要程式碼,完整程式碼地址放在了文字末尾。  1.為了更加靈活,我這裡提供了很多屬性用於使用者自己來設定:

    private String title;
    private String num;
    private String unit;

    private float titleTextsize;
    private float numTextsize;
    private float unitTextsize;

    private int titleTextColor;
    private int numTextColor;
    private int unitTextColor;

    private float backCircleWidth;
    private float outerCircleWidth;

    private int backCircleColor;
    private int outerCircleColor;

    private float endCircleWidth;
    private int endCircleColor;

2.為了程式碼更加清晰,設定瞭如下Paint

private Paint backCirclePaint,//畫背景圓
            outerCirclePaint,//畫進度圓弧
            endCirclePaint,//畫終點實心大圓
            endCirclePaint2,//畫終點實心小圓
            titlePaint,//畫第一行文字
            numPaint,//畫第二行文字
            unitPaint;//畫第三行文字

3.在onDraw方法中實現繪製操作

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

        int centerX = width / 2;
        int centerY = height / 2;

        //計算半徑
        float radius = (width / 2) - outerCircleWidth + (outerCircleWidth - backCircleWidth) / 2;


        //畫背景圓
        canvas.drawCircle(centerX, centerY, radius, backCirclePaint);

        //根據進度話掃過一定角度的圓弧
        RectF rectF = new RectF(outerCircleWidth / 2 + backCircleWidth / 2, outerCircleWidth / 2 + backCircleWidth / 2, width - outerCircleWidth / 2 - backCircleWidth / 2, height - outerCircleWidth / 2 - backCircleWidth / 2);
        canvas.drawArc(rectF, -90, 360 * currentPercent, false, outerCirclePaint);

        //畫三行文字
        Rect textRect = new Rect();

        titlePaint.getTextBounds(title, 0, title.length(), textRect);
        canvas.drawText(title, width / 2 - textRect.width() / 2, height / 4 + textRect.height() / 2, titlePaint);

        numPaint.getTextBounds(num, 0, num.length(), textRect);
        canvas.drawText(num, width / 2 - textRect.width() / 2, height / 2 + textRect.height() / 2, numPaint);

        unitPaint.getTextBounds(unit, 0, unit.length(), textRect);
        canvas.drawText(unit, width / 2 - textRect.width() / 2, height * 2 / 3 + textRect.height() / 2, unitPaint);


        //我這裡規定進度在0~100%的時候才會畫終點小圓,可以自由改動
        if (currentPercent < 1 && currentPercent > 0) {
            canvas.drawCircle(centerX + rectF.width() / 2 * (float) Math.sin(360 * currentPercent * Math.PI / 180),
                    centerY - rectF.width() / 2 * (float) Math.cos(360 * currentPercent * Math.PI / 180), endCircleWidth / 2, endCirclePaint);


            canvas.drawCircle(centerX + rectF.width() / 2 * (float) Math.sin(360 * currentPercent * Math.PI / 180),
                    centerY - rectF.width() / 2 * (float) Math.cos(360 * currentPercent * Math.PI / 180), endCircleWidth / 4, endCirclePaint2);

        }
    }

 原始碼地址:https://github.com/SolveBugs/BlogPracticeDems