Android canvas绘制方法
canvas绘制分为如下几类:
一、几何图形绘制
1. drawLine
简单的绘制一条线
canvas.drawLine(startX, startY, endX, endY, paint)

2. drawLines
如果你想要绘制多条线,相比于多次执行drawLine,我们推荐使用drawLines来完成,我们只需要提供一个坐标值的平面float数组列表,如下所示。
canvas.drawLines(floatArrayOf(startFirstX, startFirstY, endFirstX, endFirstY,startSecondX, startSecondY, endSecondX, endSecondY),paint)

3. drawPoint
虽然您可以通过以相同的起点和终点坐标画一条线来画点,这是一种技巧。我们可以使用专门提供的绘制点的方法,drawPoint函数。
canvas.drawPoint(coordinateX, coordinateY, paint)
4. drawPoints
和lines一样,你可以通过提供一个平面坐标数组来绘制多个点。
canvas.drawPoints(floatArrayOf(startX, startY,startSecondX, startSecondY),paint)
5. drawRect
使用坐标或Rect类绘制矩形。
canvas.drawRect(Rect(startX, topY, endX, bottomY), paint)

6. drawRoundRect
如果你想要绘制一个圆角矩形,可以使用drawRoundRect,它和drawRect法法很像,但是增加了两个参数radiusX和radiusY来定义圆角的弯曲程度。
canvas.drawRoundRect(rect, radiusX, radiusY, projectResources.paint)
如果radiusX等于radiusY,它将绘制均匀的圆角。

当radiusX = radiusY时,它将具有常规的圆角,如下所示:

如果radiusX 大于 radiusY 时,就会出现下面这样的效果:

如果radiusX 小于 radiusY 时,又变成了这样:

7. drawCircle
drawCircle非常简单,它只需要一个圆心坐标和半径。
canvas.drawCircle(centerCoordinateX, centerCoordinateY,radius,paint)

8. drawOval
不像绘制圆形那样,绘制椭圆时,我们不需要提供半径,而是提供一个rect,然后椭圆就会被正确绘制
canvas.drawOval(rect, paint)

9. drawArc
绘制弧形和绘制椭圆时一样的机制,使用rect,它还增加了几个参数:startAngle,sweepAngle和useCenter。
canvas.drawArc(rect, startAngle, sweepAngle, useCenter, paint)
对于startAngle,将rect的中间端作为起点,即顺时针90°。从那里开始,startAngle被认为是0°。然后从startAngle计算sweepAngle。两者都使用角度度°值。
useCenter是一个布尔变量,用于确定圆弧是否连接到中心。下图说明了useCenter为false和true之间的区别。
useCenter = false:

useCenter = true :

@Overrideprotected void onDraw(Canvas canvas) {//绘制弧线区域RectF rect = new RectF(0, 0, 100, 100);canvas.drawArc(rect, //弧线所使用的矩形区域大小0, //开始角度90, //扫过的角度false, //是否使用中心paint);}

protected void onDraw(Canvas canvas) {//绘制弧线区域RectF rect = new RectF(0, 0, 100, 100);canvas.drawArc(rect, //弧线所使用的矩形区域大小0, //开始角度90, //扫过的角度true, //是否使用中心paint);}

两图对比我们可以发现,当 drawArcs(rect,startAngel,sweepAngel,useCenter,paint)中的useCenter为false时,弧 线区域是用弧线开始角度和结束角度直接连接起来的,当useCenter为true时,是弧线开始角度和结束角度都与中心点连接,形成一个扇形。
10. drawPath
有时候,我们想画一些不限于普通几何线的东西,我们可以使用drawPath,这里的Path是一个包含了我们想要绘制路径的一个对象,它由铅笔画和移动之类的功能如moveTo和lineTo组成。
以下是我们绘制十字标记的路径的示例
val path = Path()
path.moveTo(startX, topY)
path.lineTo(endX, bottomY)
path.moveTo(startX, bottomY)
path.lineTo(endX, topY)
canvas.drawPath(path, paint)

drawPath是一个非常有用的功能。许多人使用它在Android中制作绘图应用程序。
11. drawVertices
这是一个相对复杂的函数,它以最小的点绘制三角形或顶点。例如,使用六个坐标,一个可以绘制四个三角形:

二、文本绘制
12. drawText
在Android中,我们一般使用TextView 来显示文本,但是如果你要更好的控制文本的话,如:动态更换,精准定位等等。Canvas的drawText就派上了用场。
方法如下,有text,coordinate和paint。
canvas.drawText(text, coordinateX, coordinateY, paintText)
13. Draw StaticLayout
drawText有局限性。它不会将较长的单词包装到第二行。它也不处理/n进位返回
因此,我们需要一个可将长字换行的文本到第二行来绘制的StaticLayout 。
StaticLayout实际上并不是Canvas的绘制函数,而是将自身绘制到画布中。下面是它的绘制方式:
val staticLayout =StaticLayout.Builder.obtain(TEXT, 0, TEXT.length, textPaint, width).build()canvas.save()
canvas.translate(coordinateX, coordinateY)
staticLayout.draw(canvas)
canvas.restore()
结果如下:

Staticlayout的构造函数:
public StaticLayout(CharSequence source, TextPaint paint, int width, Alignment align, float spacingmult, float spacingadd, boolean includepad) {super((CharSequence)null, (TextPaint)null, 0, (Alignment)null, 0.0F, 0.0F);throw new RuntimeException("Stub!");
}public StaticLayout(CharSequence source, int bufstart, int bufend, TextPaint paint, int outerwidth, Alignment align, float spacingmult, float spacingadd, boolean includepad) {super((CharSequence)null, (TextPaint)null, 0, (Alignment)null, 0.0F, 0.0F);throw new RuntimeException("Stub!");
}public StaticLayout(CharSequence source, int bufstart, int bufend, TextPaint paint, int outerwidth, Alignment align, float spacingmult, float spacingadd, boolean includepad, TruncateAt ellipsize, int ellipsizedWidth) {super((CharSequence)null, (TextPaint)null, 0, (Alignment)null, 0.0F, 0.0F);throw new RuntimeException("Stub!");
}
source:文本内容
paint:画笔
width:文本内容长度超过该数值则换行
align:对齐方式
spacingmult:行距,表示字体高度的倍数,默认是1,小于1则是减少行距,大于则是增加行距
spacingadd:行距,表示行间距增加的距离(与spacingmult配合使用)
includepad:是否留白
其中paint可以设置字体类型,setTypeface(),不同字体类型有着不同的绘制规则。
重要的属性有:
top,bottom,ascent,descent,baseline
通过Paint.getFontMetricsInt()可以获取到这些值,例如:mPaint.getFontMetricsInt().baseline
14. drawPosText
drawPosText使每个字符都可以放置在指定位置。在下面,单词fly被写在不同的Y位置。

API如下所示:
val posArray = listOf(x1, y1, x2, y2, x3, y3 ...).toFloatArray()
canvas.drawPosText(TEXT, startIndex, endIndex, posArray, paint)
提供的坐标点必须至少与要绘制的字母相同,否则将崩溃。
@Overrideprotected void onDraw(Canvas canvas) {//按照既定点 绘制文本内容canvas.drawPosText("Android777", new float[]{10,10, //第一个字母在坐标10,1020,20, //第二个字母在坐标20,2030,30, //....40,40,50,50,60,60,70,70,80,80,90,90,100,100}, paint);}

15. drawTextOnPath
在绘制文本的基础上加上一个路径,我们就可以沿着提供的path来绘制文本,x和y的位置相对于path给定的位置。
canvas.drawTextOnPath(TEXT, path, x, y, paint)
下面是一个V字行的路径,我们沿着path绘制文本。

16. drawTextRun
这个绘制方法就有点复杂了,因为它通常不与英语单词一起使用。它仅适用于其字母根据周围字母的可见性而绘制不同的语言。
三、颜色绘制
17. drawRGB
这个方法仅是在画布canvas上绘制颜色,这对于设置背景色非常有用
canvas.drawRGB(red, green, blue)
// Each is between 0 and 255, where 0 is not there, and 255 is full.
// When alpha is 255, it is opaque, and 0 is transparent.
18. drawARGB
和drawRGB相似,drawARGB增加了使颜色有透明度的能力。
canvas.drawARGB(alpha, red, green, blue)
// When alpha is 255, it is opaque, and 0 is transparent.
这对于设置正面颜色并使后面的项目变暗很有用。
正常图片:

设置了红色透明度的图片:

19. drawColor
使用这个方法,我们可以使用颜色资源来代替ARGB颜色,用下面这个API:
canvas.drawColor(context.getColor(R.color.colorPrimary))
20. drawPaint
有时,我们喜欢画一些奇特的颜色,代替使用ARGB或资源颜色,我们可以创建一个Paint对象。下面是一个示例:
val gradientPaint by lazy {Paint().apply {shader = RadialGradient(width/2f,height/2f,height/2f,Color.GREEN,Color.RED,Shader.TileMode.MIRROR)}
canvas.drawPaint(gradientPaint)

四、图片绘制
21. drawBitmap
给一个bitmap,我们可以将它绘制到画布上
private val bitmap by lazy {BitmapFactory.decodeResource(resources, R.drawable.image)
}
canvas.drawBitmap(bitmap, sourceRect, destRect, paint)
必须的参数是bitmap 和 destRect:
可选择的参数(可以为null)是sourceRect 和paint:
22. drawPicture
如果你想要绘制的东西组合在一起,并且要多次执行,并且您不希望处理变慢并且必须重新绘制每个时间,则可以将整个图形放入“图片(Picture)”中。
下面是一个简单的示例,其中我们将图形存储到图片中:
private val picture by lazy {val picture = Picture()val pCanvas = picture.beginRecording(width, height)pCanvas.drawBitmap(bitmap, null, rect, null)picture.endRecording()picture
}
需要时,只需执行这行代码:
canvas.drawPicture(picture)
这样可以加快整个绘制过程的速度,以完成需要一遍又一遍的绘制。
23. drawBitmapMesh
这是为了操纵绘制的位图图像。给定一个图像,我们可以在图像内设置坐标,然后将一个点平移到另一个位置,从而转换它的图像。
例如。下图的中心X,Y显示在白线横截面中。

然而,使用drawBitmapMesh,我们可以移动坐标并相应地变换图像。

标签:
相关文章
-
无相关信息
