自定義View - 仿QQ運動步數(shù)進度效果

1. 概述


我記得QQ之前是有一個,運動步數(shù)的進度效果,今天打開QQ一看發(fā)現(xiàn)沒有了。具體效果我也不清楚了,我就按照自己大概的印象寫一下,這一期我們主要是熟悉Paint畫筆的使用

2. 效果實現(xiàn)分析


2.1:畫-背景圓弧
2.2:畫-當前進度圓弧
2.3:畫-步數(shù)文字
2.4:提供一些方法

至于什么onMeasure,onDraw,自定義屬性等等我這里就不去介紹了,具體請看這里:
自定義View簡介 - onMeasure,onDraw,自定義屬性

2.1. 畫-背景圓弧

    @Override
    protected void onDraw(Canvas canvas) {
        // 2.畫背景大圓弧
        int centerX = mViewWidth / 2;
        int centerY = mViewHeight / 2;
        // 設(shè)置圓弧畫筆的寬度
        mPaint.setStrokeWidth(mRoundWidth);
        // 設(shè)置為 ROUND
        mPaint.setStrokeCap(Paint.Cap.ROUND);
        mPaint.setStrokeJoin(Paint.Join.ROUND);
        // 設(shè)置畫筆顏色
        mPaint.setColor(mRoundColor);
        mPaint.setStyle(Paint.Style.STROKE);
        // 半徑
        int radius = (int) (centerX - mRoundWidth);
        RectF oval = new RectF(centerX - radius, centerY - radius, centerX + radius, centerY + radius);
        // 畫背景圓弧
        canvas.drawArc(oval, mStartAngle, mSweepAngle, false, mPaint);
     }    

2.2:畫-當前進度圓弧

        // 畫進度圓弧
        mPaint.setColor(mProgressColor);
        // 計算當前百分比
        float percent = (float) mProgressStep/mMaxStep;
        // 根據(jù)當前百分比計算圓弧掃描的角度
        canvas.drawArc(oval, mStartAngle, percent*mSweepAngle, false, mPaint);

2.3:畫-步數(shù)文字

        // 重置畫筆
        mPaint.reset();
        mPaint.setAntiAlias(true);
        mPaint.setTextSize(mTextSize);
        mPaint.setColor(mTextColor);
        String mStep = ((int)(percent*mMaxStep)) + "";
        // 測量文字的寬高
        Rect textBounds = new Rect();
        mPaint.getTextBounds(mStep, 0, mStep.length(), textBounds);
        int dx = (getWidth() - textBounds.width()) / 2;
        // 獲取畫筆的FontMetrics
        Paint.FontMetrics fontMetrics = mPaint.getFontMetrics();
        // 計算文字的基線
        int baseLine = (int) (getHeight() / 2 + (fontMetrics.bottom - fontMetrics.top) / 2 - fontMetrics.bottom);
        // 繪制步數(shù)文字
        canvas.drawText(mStep, dx, baseLine, mPaint);

2.4. 提供一些方法

    // 設(shè)置當前最大步數(shù)
    public synchronized void setMaxStep(int maxStep) {
        if (max < 0) {
            throw new IllegalArgumentException("max 不能小于0!");
        }
        this.mMaxStep = maxStep;
    }

    public synchronized int getMaxStep() {
        return mMaxStep;
    }
    // 設(shè)置進度
    public synchronized void setProgress(int progress) {
        if (progress < 0) {
            throw new IllegalArgumentException("progress 不能小于0!");
        }
        this.progress = progress;
        // 重新刷新繪制 -> onDraw()
        invalidate();
    }

    public synchronized int getProgress() {
        return progress;
    }

invalidate()為什么會重新調(diào)用onDraw()方法?為什么我們不能在子線程更新UI ? 為何不去看看源碼

3. 請思考


我記得Hongyang寫過一篇打造炫酷的進度條,在慕課網(wǎng)上也有視頻講解,大家可以去看一下,如果你不是很熟悉自定義View,可以自己嘗試去實現(xiàn),效果如下:

58同城數(shù)據(jù)加載效果,有一部分也是Paint畫筆的使用,可以先實現(xiàn)如下效果(一秒鐘切換一次造型,不能用圖片):

所有分享大綱:Android進階之旅 - 自定義View篇

視頻講解地址:http://pan.baidu.com/s/1bpb7zIn

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容