美文网首页
绘制基础(一)- 仪表盘绘制

绘制基础(一)- 仪表盘绘制

作者: Hoker_ | 来源:发表于2018-11-29 23:08 被阅读0次
    终于到了UI绘制部分,个人还是比较感兴趣的,先从一些基本的入手。

    先准备几个基本方法:

    • dpToPixel()
        public static float dpToPixel(float dp){
            // 使用getSystem将无法获取APP本身的资源信息,但是获取系统的OK。
            return TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP,
                                             dp,
                   Resources.getSystem().getDisplayMetrics());
        }
    

    首先draw()都是关于像素的方法,显然我们需要考虑手机的适配,所以以dp来进行绘图时很有必要的,上面就是一个dp转px的方法,值得注意的是,这里免去了像其他方法一样,需要传入context,这样让调用看着更舒服。

    • canvas.drawArc()
        public void drawArc(float left, float top, float right, float bottom,
                            float startAngle,float sweepAngle, 
                            boolean useCenter,
                            Paint paint) {}
    

    参数可以分为这么几类:
       - 矩形范围,用于确定圆弧形状与尺寸的椭圆边界(即椭圆外切矩形)。
       - 开始角度和扫描角度,从矩形正中出发,都是以时钟3点的方向为0°,顺时针为正方向。(3点钟这种理解起来可能比较怪,其实就是paint坐标系的x正方向)
       - 是否包含圆心,最终绘制处理时弧还是扇形。
       - 绘制圆弧的画笔

    知道这两个,就能轻松绘制出一个弧形了。

    看一下示例代码,以及相关注释:

    public class DashboardView extends View {
    
        private final static float ANGLE = 120;
        private final static float RADIUS = UiUtils.dpToPixel(150);
        private final static int DASH_NUM = 10;
        private final static float POINT_LEN = UiUtils.dpToPixel(100);
    
        /**
         * 抗锯齿画笔
         */
        private Paint paint = new Paint(Paint.ANTI_ALIAS_FLAG);
        private Path dash = new Path();
        private PathDashPathEffect effect;
    
        public DashboardView(Context context, @Nullable AttributeSet attrs) {
            super(context, attrs);
        }
    
        // 大括号里的方法,会在构造函数中super后执行,好处就是如果有多个构造函数的话,这里只用写一份。
        {
            paint.setStyle(Paint.Style.STROKE);
            paint.setStrokeWidth(UiUtils.dpToPixel(2));
    
            // 确认刻度的大小、宽度
            // 设置的left、top、right、bottom,这些都是相对path绘制路径的
            dash.addRect(0, 0, UiUtils.dpToPixel(2), UiUtils.dpToPixel(10), Path.Direction.CCW);
    
            // 计算路径的长度
            Path arc = new Path();
            arc.addArc(getWidth() / 2 - RADIUS, getHeight() / 2 - RADIUS,
                    getWidth() / 2 + RADIUS, getHeight() / 2 + RADIUS,
                    90 + ANGLE / 2, 360 - ANGLE);
            PathMeasure measure = new PathMeasure(arc, false);
    
            // 替换原paint的效果,同时计算出两个dash之间的间距,且预留好位置,以免出格
            effect = new PathDashPathEffect(dash, (measure.getLength() - UiUtils.dpToPixel(2)) / DASH_NUM,
                    0, PathDashPathEffect.Style.ROTATE);
        }
    
        @Override
        protected void onDraw(Canvas canvas) {
            super.onDraw(canvas);
    
            // 画线
            canvas.drawArc(getWidth() / 2 - RADIUS, getHeight() / 2 - RADIUS,
                    getWidth() / 2 + RADIUS, getHeight() / 2 + RADIUS,
                    90 + ANGLE / 2, 360 - ANGLE, false, paint);
    
            // 画刻度
            paint.setPathEffect(effect);
            canvas.drawArc(getWidth() / 2 - RADIUS, getHeight() / 2 - RADIUS,
                    getWidth() / 2 + RADIUS, getHeight() / 2 + RADIUS,
                    90 + ANGLE / 2, 360 - ANGLE, false, paint);
            paint.setPathEffect(null);
    
            // 画指针
            // 启动时明确的,就是圆心,只需要确定目标点即可,通过三角函数来计算,其正方向也是X正方向出发,按顺时针来
            canvas.drawLine(getWidth()/2,getHeight()/2,
                    getWidth()/2 + (float) Math.cos(Math.toRadians(getAngleFromMark(5)))*POINT_LEN,
                    getHeight()/2 + (float) Math.sin(Math.toRadians(getAngleFromMark(5)))*POINT_LEN,
                    paint);
        }
    
        // 根据具体的刻度位置,计算出一个角度
        private int getAngleFromMark(int mark) {
            return (int)(90 + ANGLE / 2 + (360 - ANGLE) / DASH_NUM * mark);
        }
    }
    

    绘制效果:


    仪表盘

    总结:这块还是比较简单的,注意下绘制使用的一些套路即可。

    相关文章

      网友评论

          本文标题:绘制基础(一)- 仪表盘绘制

          本文链接:https://www.haomeiwen.com/subject/xnpqcqtx.html