美文网首页
Android自定义View 1-1 接上:画自定义图形

Android自定义View 1-1 接上:画自定义图形

作者: 王大碗要努力 | 来源:发表于2017-09-19 17:19 被阅读0次

    学习http://hencoder.com/ui-1-1/笔记

    一、通过drawPath()绘制自定义图形

    Path可以描述直线、二次曲线、三次曲线、圆、椭圆、弧形、矩形、圆角矩形。Path有两类方法,一类是直接描述路径的,另一类是辅助的设置或计算。

    二、Path方法第一类:直接描述路径

    这类方法可以细分为两组:添加子图形和画线(直线或曲线)

    1、addXXX():添加子图形

    addCircle(float x, float y, float radius, Direction dir) 添加圆

     /**
         * 
         * @param x
         * @param y
         * @param radius
         * @param dir  画圆的路径的方向
         */
    addCircle(float x, float y, float radius, Direction dir) 添加圆
    

    注:路径方向有两种:顺时针 (CW clockwise) 和逆时针 (CCW counter-clockwise)。 对于普通情况,这个参数填 CW 还是填 CCW 没有影响。它只是在需要填充图形 (Paint.Style 为 FILL 或 FILL_AND_STROKE) ,并且图形出现自相交时,用于判断填充范围的。

    例子:添加一个圆

    path.addCircle(300, 300, 200, Path.Direction.CW);
    ......
    canvas.drawPath(path, paint);  
    
    

    Path.add-()其他方法

    • addOval(float left, float top, float right, float bottom, Direction dir) / addOval(RectF oval, Direction dir)添加椭圆
    • addRect(float left, float top, float right, float bottom, Direction dir) / addRect(RectF rect, Direction dir) 添加矩形
    • addRoundRect(RectF rect, float rx, float ry, Direction dir) / addRoundRect(float left, float top, float right, float bottom, float rx, float ry, Direction dir) / addRoundRect(RectF rect, float[] radii, Direction dir) / addRoundRect(float left, float top, float right, float bottom, float[] radii, Direction dir) 添加圆角矩形
    • addPath(Path path) 添加另一个 Path
    2、xxxTo() ——画线(直线或曲线)

    (1)lineTo(float x, float y) / rLineTo(float x, float y) 画直线

     /**
         * 
         * @param x  目标位置X
         * @param y  目标位置y
         */
         lineTo(float x, float y) 
    

    当前位置向目标位置画一条直线, x 和 y 是目标位置的坐标。这两个方法的区别是,lineTo(x, y) 的参数是绝对坐标,而 rLineTo(x, y) 的参数是相对当前位置的相对坐标 (前缀 r 指的就是 relatively 「相对地」)。
    当前位置:所谓当前位置,即最后一次调用画 Path 的方法的终点位置。初始值为原点 (0, 0)。

    paint.setStyle(Paint.Style.STROKE);
            path.lineTo(100, 100); // 由当前位置 (0, 0) 向 (100, 100) 画一条直线  
            path.rLineTo(100, 0); // 由当前位置 (100, 100) 向正右方 100 像素的位置画一条直线  
            canvas.drawPath(path, paint); 
    
    连线

    (2)quadTo(float x1, float y1, float x2, float y2) / rQuadTo(float dx1, float dy1, float dx2, float dy2) 画二次贝塞尔曲线
    参数:这条二次贝塞尔曲线的起点就是当前位置,而参数中的 x1, y1 和 x2, y2 则分别是控制点和终点的坐标。和 rLineTo(x, y) 同理,rQuadTo(dx1, dy1, dx2, dy2) 的参数也是相对坐标

    (3)cubicTo(float x1, float y1, float x2, float y2, float x3, float y3) / rCubicTo(float x1, float y1, float x2, float y2, float x3, float y3) 画三次贝塞尔曲线

    (4)moveTo(float x, float y) / rMoveTo(float x, float y) 移动到目标位置

    paint.setStyle(Paint.Style.STROKE);
            paint.setStrokeWidth(10);
            path.lineTo(100, 100); // 画斜线  
            path.moveTo(200, 200); // 我移~~  
            path.lineTo(200, 0); // 画竖线 
            canvas.drawPath(path, paint); 
    
    移动位置

    (5)arcTo(RectF oval, float startAngle, float sweepAngle, boolean forceMoveTo) / arcTo(float left, float top, float right, float bottom, float startAngle, float sweepAngle, boolean forceMoveTo) / arcTo(RectF oval, float startAngle, float sweepAngle) 画弧形
    参数 forceMoveTo :绘制是要「抬一下笔移动过去」,还是「直接拖着笔过去」,区别在于是否留下移动的痕迹。
    addArc(float left, float top, float right, float bottom, float startAngle, float sweepAngle) / addArc(RectF oval, float startAngle, float sweepAngle)

    (6)close() 封闭当前子图形
    作用是把当前的子图形封闭,即由当前位置向当前子图形的起点绘制一条直线。

    paint.setStyle(Paint.Style.STROKE);
            paint.setStrokeWidth(10);
            path.moveTo(100, 100);
            path.lineTo(200, 100);
            path.lineTo(150, 150);
            path.close();
            canvas.drawPath(path, paint);
    
    1.png 2.png

    当需要填充,不需要close() 。Paint.Style 为 FILL 或 FILL_AND_STROKE,Path 会自动封闭子图形。

     paint.setStyle(Paint.Style.FILL);
            paint.setStrokeWidth(10);
            path.moveTo(100, 100);
            path.lineTo(200, 100);
            path.lineTo(150, 150);
            canvas.drawPath(path, paint); 
    
    填充
    三、Path方法第二类:辅助的设置或计算

    1.Path.setFillType(Path.FillType ft) 设置填充方式
    在二.1画圆中,参数 Direction dir提到, Path.setFillType(fillType) 是用来设置图形自相交时的填充算法的,不同的FillType值,有不同的填充效果。FillType的四种取值:

    • EVEN_ODD
    • WINDING (默认值)
    • INVERSE_EVEN_ODD
    • INVERSE_WINDING

    (1)EVEN_ODD
    即 even-odd rule (奇偶原则):对于平面中的任意一点,向任意方向射出一条射线,这条射线和图形相交的次数(相交才算,相切不算哦)如果是奇数,则这个点被认为在图形内部,是要被涂色的区域;如果是偶数,则这个点被认为在图形外部,是不被涂色的区域。射线每穿过图形中的一条线,内外状态就发生一次切换,这就是为什么 EVEN_ODD 是一个「交叉填充」的模式。
    (2)WINDING
    non-zero winding rule (非零环绕数原则),首先,它需要你图形中的所有线条都是有绘制方向的:以 0 为初始值,顺时针+1,逆时针-1。结果不为0,则在图形内部,涂色;结果为0,则在图形外部,不被涂色。
    (3)INVERSE_EVEN_ODD和 INVERSE_WINDING
    与前两个相反

    相关文章

      网友评论

          本文标题:Android自定义View 1-1 接上:画自定义图形

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