作者:扔物线
链接:https://juejin.im/post/5962a3746fb9a06ba2687226
来源:掘金
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
Paint类的几个最常用的方法。具体是:
1.Paint.setStyle(Style style)设置绘制模式
setStyle(Style style)这个方法设置的是绘制的Style。Style具体来说有三种:FILL,STROKE和FILL_AND_STROKE。FILL是填充模式,STROKE是画线模式(即勾边模式),FILL_AND_STROKE是两种模式一并使用:既画线又填充。它的默认值是FILL,填充模式。
2.Paint.setColor(int color)设置颜色
3.Paint.setStrokeWidth(float width)设置线条宽度
在STROKE和FILL_AND_STROKE下,还可以使用paint.setStrokeWidth(float width)
4.Paint.setTextSize(float textSize)设置文字大小
5.Paint.setAntiAlias(boolean aa)设置抗锯齿开关
在绘制的时候,往往需要开启抗锯齿来让图形和文字的边缘更加平滑.另外,还可以在创建Paint对象的时候,直接设置抗锯齿
Paint paint = new Paint(Paint.ANTI_ALIAS_FLAG);
因为抗锯齿的原理是:修改图形边缘处的像素颜色,从而让图形在肉眼看来具有更加平滑的感觉。
二、绘图Api
1.canvas.drawColor(@ColorInt int color) 颜色填充
drawColor(Color.BLACK)会把整个区域染成纯黑色,覆盖掉原有内容;
drawColor(Color.parse("#88880000")会在原有的绘制效果上加一层半透明的红色遮罩。
2.canvas.drawCircle(float centerX, float centerY, float radius, Paint paint) 画圆
centerX,centerY 是圆心坐标,radius是半径
3.canvas.drawRect(RectF rect, Paint paint) 画矩形 是具有兼容性的,一般我喜欢用这个
RectF rect = new RectF(100,100,300,300);分别代表左上点的坐标和右下点的坐标,构成一个矩形
4.canvas.drawPoint(float x, float y, Paint paint) 画点
点的大小可以通过paint.setStrokeWidth(width)来设置;点的形状可以通过paint.setStrokeCap(cap)来设置:ROUND画出来是圆形的点,SQUARE或BUTT画出来是方形的点。
Paint.Cap.ROUND 圆形的点
Paint.Cap.SQUARE / Paint.Cap.BUTT 放形的点
5.canvas.drawPoints(float[] pts, int offset, int count, Paint paint) 一次性的化多个点
pts这个数组是点的坐标,每两个成一对;offset表示跳过数组的前几个数再开始记坐标;count表示一共要绘制几个点。
6.canvas.drawPoints(float[] pts, Paint paint) 画点(批量)
pts这个数组是点的坐标,每两个成一对;
7.canvas.drawOval(RectF rect, Paint paint)画椭圆
RectF 是矩形,其实就是规定在一个矩形里面画一个椭圆
8.canvas.drawLine(float startX, float startY, float stopX, float stopY, Paint paint) 画线
float startX, float startY 起始点
float stopX, float stopY 终止点
9.canvas.drawLines(float[] pts, int offset, int count, Paint paint) 批量画线
10.canvas.drawRoundRect(RectF rect, float rx, float ry, Paint paint) 画圆角的矩形
RectF rect 规定一个矩形
float rx, float ry 圆角矩形的圆角的横向半径和纵向半径
11.canvas.drawArc(float left, float top, float right, float bottom, float startAngle, float sweepAngle, boolean useCenter, Paint paint) 绘制弧形或扇形
drawArc()是使用一个椭圆来描述弧形的。left,top,right,bottom描述的是这个弧形所在的椭圆;
startAngle是弧形的起始角度(x 轴的正向,即正右的方向,是 0 度的位置;顺时针为正角度,逆时针为负角度),
sweepAngle是弧形划过的角度;
useCenter表示是否连接到圆心,如果不连接到圆心,就是弧形,如果连接到圆心,就是扇形。
12.canvas.drawPath(Path path, Paint paint) 画自定义图形
drawPath(path)这个方法是通过描述路径的方式来绘制图形的,它的path参数就是用来描述图形路径的对象。path的类型是Path
三、Path 相关绘制方法与说明
Path path = new Path();
...........path的相关方法
最后别忘记:canvas.drawPath(path,paint);
1.path.addCircle(float x, float y, float radius, Direction dir) 添加圆
参数dir是画圆的路径的方向
顺时针 (CWclockwise) 和逆时针 (CCWcounter-clockwise) 。对于普通情况,这个参数填CW还是填CCW没有影响。它只是在需要填充图形(Paint.Style为FILL或FILL_AND_STROKE) ,并且图形出现自相交时,用于判断填充范围的
2.path.addOval(float left, float top, float right, float bottom, Direction dir) / addOval(RectF oval, Direction dir) 添加椭圆
3.path.addRect(float left, float top, float right, float bottom, Direction dir) / addRect(RectF rect, Direction dir) 添加矩形
4.path.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) 添加圆角矩形
5.path.addPath(Path path) 添加另一个 Path
6.path.lineTo(float x, float y) / rLineTo(float x, float y) 画直线
从当前位置向目标位置画一条直线,x和y是目标位置的坐标。这两个方法的区别是,lineTo(x, y)的参数是绝对坐标,而rLineTo(x, y)的参数是相对当前位置的相对坐标(前缀r指的就是relatively「相对地」)。
当前位置:所谓当前位置,即最后一次调用画Path的方法的终点位置。初始值为原点 (0, 0)。
7.path.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)的参数也是相对坐标
8.path.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) 画三次贝塞尔曲线
9.path.moveTo(float x, float y) / rMoveTo(float x, float y) 移动到目标位置,可以指定起点
不论是直线还是贝塞尔曲线,都是以当前位置作为起点,而不能指定起点。但你可以通过moveTo(x, y)或rMoveTo()来改变当前位置,从而间接地设置这些方法的起点。
moveTo(x, y)虽然不添加图形,但它会设置图形的起点,所以它是非常重要的一个辅助方法。
10.path.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) 画弧形
这个方法和Canvas.drawArc()比起来,少了一个参数useCenter,而多了一个参数forceMoveTo。
少了useCenter,是因为arcTo()只用来画弧形而不画扇形,所以不再需要useCenter参数;而多出来的这个forceMoveTo参数的意思是,绘制是要「抬一下笔移动过去ture」,还是「直接拖着笔过去false」,区别在于是否留下移动的痕迹。
11.path.addArc(float left, float top, float right, float bottom, float startAngle, float sweepAngle) / addArc(RectF oval, float startAngle, float sweepAngle)
又是一个弧形的方法。一个叫arcTo,一个叫addArc(),都是弧形,区别在哪里?其实很简单:addArc()只是一个直接使用了forceMoveTo = true的简化版arcTo()。即,抬起一下笔移动过去,中间有隔断的部分,不是连着的
12.path.close() 封闭当前子图形
它的作用是把当前的子图形封闭,即由当前位置向当前子图形的起点绘制一条直线。
close()和lineTo(起点坐标)是完全等价的。
13.path.setFillType(FillType fillType)
顺时针 (CWclockwise) 和逆时针 (CCWcounter-clockwise) 。对于普通情况,这个参数填CW还是填CCW没有影响。它只是在需要填充图形(Paint.Style为FILL或FILL_AND_STROKE) ,并且图形出现自相交时,用于判断填充范围的。Path.setFillType(fillType)是用来设置图形自相交时的填充算法的:
FillType的取值有四个:
EVEN_ODD
对于平面中的任意一点,向任意方向射出一条射线,这条射线和图形相交的次数(相交才算,相切不算哦)如果是奇数,则这个点被认为在图形内部,是要被涂色的区域;如果是偶数,则这个点被认为在图形外部,是不被涂色的区域。还以左右相交的双圆为例:
WINDING(默认值)
首先,它需要你图形中的所有线条都是有绘制方向的:
同样是从平面中的点向任意方向射出一条射线,但计算规则不一样:以 0 为初始值,对于射线和图形的所有交点,遇到每个顺时针的交点(图形从射线的左边向右穿过)把结果加 1,遇到每个逆时针的交点(图形从射线的右边向左穿过)把结果减 1,最终把所有的交点都算上,得到的结果如果不是 0,则认为这个点在图形内部,是要被涂色的区域;如果是 0,则认为这个点在图形外部,是不被涂色的区域。
图形的方向:对于添加子图形类方法(如Path.addCircle()Path.addRect())的方向,由方法的dir参数来控制,这个在前面已经讲过了;而对于画线类的方法(如Path.lineTo()Path.arcTo())就更简单了,线的方向就是图形的方向。
完整版的EVEN_ODD和WINDING的效果应该是这样的
INVERSE_EVEN_ODD
INVERSE_WINDING
14.path.drawBitmap(Bitmap bitmap, float left, float top, Paint paint) 画 Bitmap
把bitmap绘制到left,top的坐标点的位置上
15.path.drawText(String text, float x, float y, Paint paint) 绘制文字
在x,y的坐标位置绘制文字内容
可以用paint.setTextSize(float textSize) 设置的文字大小