Android閃屏頁圓形倒數計時進度條實現

xinyang_code發表於2017-12-14

前言

現在我們的App中基本都會有閃屏頁面,而閃屏頁中大多又都會加入廣告資訊或者我們自己logo等宣傳圖片的展示,類似如下效果:

閃屏頁效果

思路

使用自定義View,通過View的重繪方法Invalidate()onDraw()中不斷繪製不同弧度的圓弧來改變顯示進度,是不是很簡單?下面就來一起看一下具體的實現啦~

  1. 確定繪製位置,首先在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;
複製程式碼

矩形邊距要計算畫筆寬度的原因

  1. 繪製背景顏色,這裡一半都是給一個半透明的顏色,因為這裡面一半都會顯示個跳過或者倒數計時時間的文字,不透明看不到下面的圖片,全透明又有可能字型顏色和底部圖片顏色近似而看不清。so~ 調整下畫筆顏色和填充模式就好啦,canvas背景色要設定為全透明:
        //設定畫布為透明
        canvas.drawColor(Color.TRANSPARENT);

        //畫個半透明的圓當背景
        mPaint.setColor(Color.parseColor("#33000000"));
        //設定畫筆為填充模式
        mPaint.setStyle(Paint.Style.FILL);
        //畫一個橢圓
        canvas.drawOval(mRectF, mPaint);
複製程式碼
  1. 調整畫筆屬性 繪製圓弧,這裡需要注意的是繪製圓弧時的起始角度是三點鐘方向是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);
複製程式碼
  1. 時間進度計算 這裡的方法有待優化,感覺不是特別好。現在是通過迴圈控制短時間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

有問題和建議歡迎留言告知啦~~

相關文章