前言
現在我們的App中基本都會有閃屏頁面,而閃屏頁中大多又都會加入廣告資訊或者我們自己logo等宣傳圖片的展示,類似如下效果:
思路
使用自定義View,通過View的重繪方法Invalidate()
在onDraw()
中不斷繪製不同弧度的圓弧來改變顯示進度,是不是很簡單?下面就來一起看一下具體的實現啦~
- 確定繪製位置,首先在
onDraw()
中獲取View的寬高,定義出一個矩形為我們的繪製範圍:
int width = this.getWidth();
int height = this.getHeight();
if (width != height) {
int min = Math.min(width, height);
width = min;
height = min;
}
//定義矩形的上下左右位置 mStrokeWidth為畫筆的寬度
//為什麼要從畫筆寬度/2位置開始,請看下圖啦,紅色是畫筆的路徑,黑色就是我們定義的矩形位置
mRectF.left = mStrokeWidth / 2;
mRectF.top = mStrokeWidth / 2;
mRectF.right = width - mStrokeWidth / 2;
mRectF.bottom = height - mStrokeWidth / 2;
複製程式碼
- 繪製背景顏色,這裡一半都是給一個半透明的顏色,因為這裡面一半都會顯示個跳過或者倒數計時時間的文字,不透明看不到下面的圖片,全透明又有可能字型顏色和底部圖片顏色近似而看不清。so~ 調整下畫筆顏色和填充模式就好啦,canvas背景色要設定為全透明:
//設定畫布為透明
canvas.drawColor(Color.TRANSPARENT);
//畫個半透明的圓當背景
mPaint.setColor(Color.parseColor("#33000000"));
//設定畫筆為填充模式
mPaint.setStyle(Paint.Style.FILL);
//畫一個橢圓
canvas.drawOval(mRectF, mPaint);
複製程式碼
- 調整畫筆屬性 繪製圓弧,這裡需要注意的是繪製圓弧時的起始角度是三點鐘方向是0度,12點方向是-90度。
//設定畫筆
mPaint.setAntiAlias(true); //抗鋸齒
mPaint.setColor(paintColor); //設定畫筆顏色
mPaint.setStyle(Paint.Style.STROKE); //設定畫筆填充模式
mPaint.setStrokeWidth(mStrokeWidth); //設定畫筆寬度
//繪製圓弧 第一個引數是我們定義好的矩形,用來控制繪製區域,也可以直接傳入上下左右四個邊框的距離來控制
// 第二個引數是圓弧的起始角度
// 第三個引數是繪製的角度範圍,主要就是通過這個引數控制
// 第四個參數列示是否連線到圓心,true連線了就是扇形了 false不連線就是圓弧
// mProgress是當前進度,-號是為了控制繪製方向
canvas.drawArc(mRectF, -90, -(mProgress / mMaxProgress) * 360, false, mPaint);
複製程式碼
- 時間進度計算 這裡的方法有待優化,感覺不是特別好。現在是通過迴圈控制短時間sleep,使用View的重繪方法來更新繪製進度,這裡需要注意的是在子執行緒必須呼叫
postInvalidate()
方法來進行重繪。
/**
* 開始倒數計時
*
* @param time 倒數計時時間 毫秒值
*/
public void startDownTime(final long time) {
//最大進度
mMaxProgress = 100;
//開啟子執行緒來做睡眠操作
new Thread(new Runnable() {
@Override
public void run() {
for (int i = (int) mMaxProgress; i >= 0; i--) {
try {
Thread.sleep((long) (time / mMaxProgress));
} catch (InterruptedException e) {
e.printStackTrace();
}
mProgress = (float) i;
//子執行緒中必須呼叫這個重繪方法 invalidate()只能在ui執行緒呼叫
ProgressView.this.postInvalidate();
}
}
}).start();
}
複製程式碼
總結
可以通過改變最後一步集合的遍歷方法來改變進度條的方式,通過繪製時的角度正負來控制方向等等。原始碼Demo可以從這裡下載:點此跳轉Github
有問題和建議歡迎留言告知啦~~