自定義View的簡單實踐01-儀表盤

1.成品展示11122

image.png

2.思路分析

這是一個很簡單的儀表盤較為簡單單調的儀表盤。
第一步,我們要畫一個弧形(Canvas.drawArc())。
第二步,畫出均勻刻度。
第三步,畫指針。

3.具體實現(xiàn)

3.1 畫弧形

    //1,畫弧形
    //角度
    private static final int ANGLE = 120;
    //半徑
    private static final float RADIOUS = DpToPxUtil.dp2px(150);
    //刻度盤弧形寬度
    private static final float dashBoardWidth = DpToPxUtil.dp2px(2);

    private Paint mPaint = new Paint(Paint.ANTI_ALIAS_FLAG);

    {
        mPaint.setStyle(Paint.Style.STROKE);
        mPaint.setStrokeWidth(dashBoardWidth);
    }

canvas.drawArc(getWidth()/2 - RADIOUS,getHeight()/2 - RADIOUS,getWidth()/2 + RADIOUS,getHeight()/2 + RADIOUS,90 + ANGLE/2,360 - ANGLE,false,mPaint);
image.png

3.2.畫刻度

畫刻度,這里需要PathDashPathEffect (PathDashPathEffect 詳解 2.5.4)

mPath.addRect(0,0,DpToPxUtil.dp2px(2),DpToPxUtil.dp2px(10),Path.Direction.CW);
mPathDashPathEffect = new PathDashPathEffect(mPath,50,0,PathDashPathEffect.Style.ROTATE);
mPaint.setPathEffect(mPathDashPathEffect);

效果

image.png

這里我們看到他只是畫出了虛線的刻度盤,因為這里PathDashPathEffect并不是給我們添加一個特效,而是將我們繪制的效果改成我們所需要的效果。所以這里我們需要先畫一次圓弧,然后再添加特效。

3.2.1.添加弧形
        mPaint.reset();
        mPaint.setStyle(Paint.Style.STROKE);
        mPaint.setStrokeWidth(dashBoardWidth);
        canvas.drawArc(getWidth()/2 - RADIOUS,getHeight()/2 - RADIOUS,getWidth()/2 + RADIOUS,getHeight()/2 + RADIOUS,90 + ANGLE/2,360 - ANGLE,false,mPaint);
3.2.2.添加刻度
        //添加虛線刻度
        mPath.addRect(0,0,DpToPxUtil.dp2px(2),DpToPxUtil.dp2px(10),Path.Direction.CW);

        //測量弧形長度
        mPathArc.addArc(getWidth()/2 - RADIOUS,getHeight()/2 - RADIOUS,getWidth()/2 + RADIOUS,getHeight()/2 + RADIOUS,90 + ANGLE/2,360 - ANGLE);
        mPathMeasure = new PathMeasure(mPathArc,false);
        mPathDashPathEffect = new PathDashPathEffect(mPath,mPathMeasure.getLength()/20,0,PathDashPathEffect.Style.ROTATE);

        //2.畫刻度
        mPaint.setPathEffect(mPathDashPathEffect);
        canvas.drawArc(getWidth()/2 - RADIOUS,getHeight()/2 - RADIOUS,getWidth()/2 + RADIOUS,getHeight()/2 + RADIOUS,90 + ANGLE/2,360 - ANGLE,false,mPaint);

注:這里有一個地方需要注意。
這里我們需要畫20個刻度,所以我們需要先測量出弧形的總長度,然后除以20,然后的出刻度的間隙,然后再畫出刻度。這樣的結果如圖


image.png

這里注意到最后一個刻度沒有畫出來?。?!


image.png

這里是因為我們的刻度是有寬度的,當我們計算刻度的間距的,我們需要20個間距,21個刻度值,所以我們這里計算間距的時候,應該用弧形的長度減去最后一個刻度的寬度然后再除以20;

        //測量弧形長度
        mPathArc.addArc(getWidth()/2 - RADIOUS,getHeight()/2 - RADIOUS,getWidth()/2 + RADIOUS,getHeight()/2 + RADIOUS,90 + ANGLE/2,360 - ANGLE);
        mPathMeasure = new PathMeasure(mPathArc,false);
        mPathDashPathEffect = new PathDashPathEffect(mPath,(mPathMeasure.getLength() - DpToPxUtil.dp2px(2))/20,0,PathDashPathEffect.Style.ROTATE);
image.png

嘿嘿,好了,你說氣人不!?。?/p>

image.png

3.3 畫指針

        //3.畫指針
        canvas.drawLine(
                getWidth()/2,
                getHeight()/2,
                getWidth()/2 + (float)Math.cos(Math.toRadians(getCurrentMark(14))) * pointLength,
                getHeight()/2 + (float)Math.sin(Math.toRadians(getCurrentMark(6))) * pointLength,
                mPaint);

這里畫指針需要獲取指針所對應的刻度的角度,這里對應這個這個儀表盤的刻度封裝了對應的方法。

 //獲取對應刻度的角度
    private int getCurrentMark(int mark){
        return (int)(90 + (float)ANGLE/2 + (360 - (float)ANGLE)/20 * mark);
    }

這里因為指針是從弧形刻度的左下角開始的,所以要先加上弧形起始角度(90 + (float)ANGLE/2)。
隨后,根據(jù)用戶給出的刻度值mark,然后計算出對應刻度所占的角度大?。?(360 - (float)ANGLE)/20 * mark)。
然后將兩個值相加,得到mark所都對應的角度值。

附:
這里 DpToPxUtil.dp2px(2) 為dp 像素轉換工具類

public static float dp2px(float dp){
        return TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP,dp, Resources.getSystem().getDisplayMetrics());
    }

到此,簡單的儀表盤做好了!
Demo:CMViewDemo Github地址

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

相關閱讀更多精彩內容

友情鏈接更多精彩內容