1. 程式人生 > >Android自定義View完美實現指示器位置隨進度變化的IndicateProgressView

Android自定義View完美實現指示器位置隨進度變化的IndicateProgressView

該文章同步釋出在公眾號”LinminTech”上,請在本文最後掃碼關注,獲取更多精彩Android開發文章。

效果圖

這裡寫圖片描述

需求

在平時開發過程中,UI經常要求實現如上圖所示的ProgressBar,但是Android系統自帶的ProgressBar並不能滿足我們的要求,這就要求我們自定義實現這樣的控制元件。

基本原理

在網上看到很多類似直接繼承系統ProgressBar來實現此控制元件,但是在實現進度指示器都比較複雜,這裡介紹一種比較簡單的實現方式。
基本原理:

第一步畫Progress預設背景矩形框

此預設背景矩形框鋪滿我們自己定義的寬度。程式碼如下

int
width = getWidth(); int height = getHeight(); //畫背景 RectF backRectF = new RectF(0, height * 2 / 5, width, height * 3 / 5); backPaint.setColor(backgroundColor); canvas.drawRoundRect(backRectF, radius, radius, backPaint);

第二步畫Progress進度矩形框

此進度矩形框是蓋在背景矩形框之上的。

//畫進度
RectF progressRectF = new RectF(0, height * 2
/ 5, width * getScale(), height * 3 / 5); LinearGradient lGradient = new LinearGradient(0, height * 2 / 5, width * getScale(), height * 3 / 5, startProgressColor, endProgressColor, Shader.TileMode.MIRROR); progressPaint.setShader(lGradient); canvas.drawRoundRect(progressRectF, radius, radius, progressPaint);

第三步畫進度百分比指示器矩形框

此進度百分比指示器是蓋在進度矩形框之上。

//畫指示器邊框
float left = width * getScale() - indicateTextPaint.measureText(PERCENT_STR) - defaultIndicateMargin;
float right = width * getScale();
if (getScale() <= 0.5) {
    left = width * getScale() - defaultIndicateMargin;
    right = left + indicateTextPaint.measureText(PERCENT_STR) +   defaultIndicateMargin;
}
if (left <= 0f) {
    left = 0f;
    right = indicateTextPaint.measureText(PERCENT_STR) + defaultIndicateMargin;
}
if (right <= indicateTextPaint.measureText(PERCENT_STR) + defaultIndicateMargin) {
    right = indicateTextPaint.measureText(PERCENT_STR) + defaultIndicateMargin;
}
RectF indicatorRectF = new RectF(left, height / 5, right, height * 4 / 5);
indicateBackPaint.setColor(indicateTextColor);
canvas.drawRoundRect(indicatorRectF, indicatorRadius, indicatorRadius, indicateBackPaint);

//畫指示器內部為白色
RectF indicatorContentRectF = new RectF(left + defaultContentMargin, height / 5 + defaultContentMargin,right - defaultContentMargin, height * 4 / 5 - defaultContentMargin);
indicateBackPaint.setColor(Color.WHITE);
canvas.drawRoundRect(indicatorContentRectF, indicatorRadius, indicatorRadius, indicateBackPaint);

第四步畫進度百分比文字

此文字是在指示器內部顯示。

//畫指示器文字
float textX = indicatorContentRectF.centerX() - indicateTextPaint.measureText(indicateText) / 2;
float textY = height * 3 / 5;
canvas.drawText(indicateText, textX, textY, indicateTextPaint);

幾個要點說明

說明圖
這篇文章我介紹的實現方法,比較麻煩的是進度指示器indicator的座標、進度百分比文字的座標,以及自定義顏色漸變的實現。這裡我們假設定義indicator的寬度為indicator.width。

確定進度指示器的座標

圖一:
indicator的最右邊與進度條progress最右邊重合,所以indicator.x為進度條progress.right - - defaultIndicateMargin(預設間距)。
圖二:
indicator在最左端時,indicator.x為0,indicator.right為indicator.width。
圖三:
indicator在最右端時,indicator.right為整個view的width,indicator.x為width - indicator.width。

確定進度百分比文字的座標

以上任一種情況下,進度百分比文字的座標text.x,text.y是怎樣的呢?
text.x = indicatoRectF.centerX - indicatorTextPaint.measure(“百分比文字”) / 2,
因為此文字一直都是垂直居中的(我是整個view的高度分為5等份,進度條佔1等份,指示器indicator佔3等份,上下空白各佔1等份),text.y(text.baseline) = view.height * 3 / 5。

顏色漸變的實現

利用線性顏色漸變LinearGradient來實現,如下:

LinearGradient lGradient = new LinearGradient(0, height * 2 / 5, width * getScale(), height * 3 / 5, startProgressColor, endProgressColor, Shader.TileMode.MIRROR);
progressPaint.setShader(lGradient);

原始碼下載

掃碼關注,獲取更多精彩Android開發文章
LinminTech