Android開發:Android自定義View
阿新 • • 發佈:2018-12-09
本文為博主- 山水相逢-z 原創文章,地址: https://blog.csdn.net/weixin_38251977/article/details/82286127
上週遇到一個需求,用一個圓形進度條的形式來展示某項操作所佔的比例,雖然類似的輪子已經有很多了,但是這種簡單的自定義View個人覺得有時間的話,還是自己寫寫比較好。
首先來看一下效果圖:
分析: 從效果圖可以看到,這個效果整體分為以下幾部分:
- 背景圓環
- 進度圓弧
- 終點小圓圈(進度為0和進度為100%的時候應當沒有)
- 內部三行文字
怎麼實現: 分析出整體框架之後,思路其實已經很簡單了,我是這樣實現的:
- 畫背景圓
- 按照當前進度計算出掃過的弧度來畫一個圓弧
- 以第二步的圓弧結束位置為座標,畫兩個大小不同的實心圓,達到設計效果
- 分別畫三行文字
第三步中,在確定圓弧終點位置的時候用到了三角函式,這裡簡單畫了一個圖,很好理解:
以頂點為起點,圓半徑為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); } }