在 Compose
中,绘制的 Api
有 drawBehind
drawWithContent
或者是使用完成自定义绘制方式 Canvas,接下来就来看看他们是如何使用的
在已有内容上绘制
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
|
@Preview
@Composable
fun View1() {
// drawBehind behind:后面
Text(text = "绘制", modifier = Modifier.drawBehind {
// 绘制背景
this.drawRect(Color.Yellow)
// 绘制线
this.drawLine(
Color.Red,
start = Offset(0f, size.height / 2), // 起始位置
end = Offset(size.width, size.height / 2) // 结束位置
)
})
}
|
behind 的中文翻译意思是后面,drawBehind 可以理解为,会在已有内容的后面进行绘制,而上述代码中的意思,就是在 text 文字的后面绘制,上述代码中,我们绘制了一个黄色背景,和画了一条线,运行后是这样的
在这里我们注意到一个区别,那就是绘制背景 drawRect 的时候,并没有填入绘制的范围,这又是哪里设置了呢,起始是 drawRect 中默认参数的,而大小的 size 信息,都是 DrawScope 类中提供了,如果是 Android 原生的话,这些都需要自己填写,会麻烦很多,Compose 在这方面遥遥领先
在 DrawScope 的中,也提供了非常多绘制 Api,这些 Api 都大同小异,基本和原生差不多
完全绘制内容
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
|
@Preview
@Composable
fun View2() {
Box(modifier = Modifier
.size(50.dp)
.drawWithContent {
drawRect(Color.Green) // 绘制在内容的底部
drawContent() // 绘制原有内容
// 绘制在内容的上面
this.drawLine(
Color.Red,
start = Offset(0f, size.height / 2),
end = Offset(size.width, size.height / 2)
)
})
}
|
我们想要完全自定义绘制内容的时候,可以使用 drawWithContent 参数,然后在 drawWithContent 的上面的代码,是在原有绘制内容的底部,在下面部分的代码是绘制在原有内容的上面部分,最后运行代码后是这样的
在 Android 原生中,一般完全绘制内容的时候,我们会使用 Canvas 这个类,比如一般是这样的
1
2
3
4
5
6
7
8
9
10
|
class CustomView @JvmOverloads constructor(
context: Context, attrs: AttributeSet? = null, defStyleAttr: Int = 0
) : View(context, attrs, defStyleAttr) {
override fun onDraw(canvas: Canvas) {
super.onDraw(canvas)
canvas.drawLine()
canvas.drawRect()
}
}
|
其实在 Compose 也有类似这样的使用方式,上面的代码,转化后,是这样的
图片的几何变化, 拉升和缩放,旋转
1
2
3
4
5
6
7
8
9
10
11
|
@Preview
@Composable
fun View3() {
val image = ImageBitmap.imageResource(id = R.mipmap.ccc)
Canvas(modifier = Modifier.size(height = image.height.dp, width = image.width.dp)) {
rotate(degrees = 0f) { // 旋转
drawImage(image, dstSize = IntSize(size.width.toInt(), size.height.toInt()))
}
}
}
|
绘制图片使用的是 drawImage ,这里和原生的区别是,原生使用的是 drawBitmap ,而且需要设置 rect 等很多参数设置,而在 compose 则是会简单很多,运行后,效果是这样的
一维旋转
如果我们想对上面的图片进行旋转呢,使用到的是 rotate ,相对比原生的话,也会简单很多,如果是原生的话,需要对 canvas 画布进行操作,操作之后,还得将画布还原回来,而在 Compose 中,底层虽然也是使用的 Canvas ,但都是内部进行处理还原了,不用我们手动处理了
1
2
3
4
5
6
7
8
9
10
11
12
13
14
|
class CustomView @JvmOverloads constructor(
context: Context, attrs: AttributeSet? = null, defStyleAttr: Int = 0
) : View(context, attrs, defStyleAttr) {
val paint = Paint()
override fun onDraw(canvas: Canvas) {
super.onDraw(canvas)
canvas.save()
canvas.rotate(90f)
canvas.drawBitmap()
canvas.restore()
}
}
|
而如果是 Compose 中
1
2
3
4
5
6
7
8
9
10
11
|
@Preview
@Composable
fun View3() {
val image = ImageBitmap.imageResource(id = R.mipmap.ccc)
Canvas(modifier = Modifier.size(height = image.height.dp, width = image.width.dp)) {
rotate(degrees = 45f) { // 平面旋转, 或者是 graphicsLayer 也可以做到
drawImage(image, dstSize = IntSize(size.width.toInt(), size.height.toInt()))
}
}
}
|