android 自定义图形,Android自定义View 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);

95a3d0e04df0

连线

(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);

95a3d0e04df0

移动位置

(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);

95a3d0e04df0

1.png

95a3d0e04df0

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);

95a3d0e04df0

填充

三、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

与前两个相反

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值