自定义View的简单实践01-仪表盘

1.成品展示11122

自定义View的简单实践01-仪表盘_第1张图片
image.png

2.思路分析

这是一个很简单的仪表盘较为简单单调的仪表盘。
第一步,我们要画一个弧形(Canvas.drawArc())。
第二步,画出均匀刻度。
第三步,画指针。

3.具体实现

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);
自定义View的简单实践01-仪表盘_第2张图片
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);

效果

自定义View的简单实践01-仪表盘_第3张图片
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,然后的出刻度的间隙,然后再画出刻度。这样的结果如图


自定义View的简单实践01-仪表盘_第4张图片
image.png

这里注意到最后一个刻度没有画出来!!!


自定义View的简单实践01-仪表盘_第5张图片
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);
自定义View的简单实践01-仪表盘_第6张图片
image.png

嘿嘿,好了,你说气人不!!!


自定义View的简单实践01-仪表盘_第7张图片
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)。
随后,根据用户给出的刻度值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地址

你可能感兴趣的:(自定义View的简单实践01-仪表盘)