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
,我们可以移动坐标并相应地变换图像。
标签:
相关文章
-
无相关信息