Jetpack Compose draw text 笔记

DrawScope.kt 看提供了众多的drawXXX, 而唯独没有看到drawText, 这不是坑爹吗
在这里插入图片描述

DrawScope 看到 val drawContext: DrawContext
DrawContext.kt

package androidx.compose.ui.graphics.drawscope

import androidx.compose.ui.geometry.Size
import androidx.compose.ui.graphics.Canvas
interface DrawContext {

    /**
     * The current size of the drawing environment
     */
    var size: Size

    /**
     * The target canvas to issue drawing commands
     */
    val canvas: Canvas

    /**
     * The controller for issuing transformations to the drawing environment
     */
    val transform: DrawTransform
}

这个canvas 看着眼熟,

在这里插入图片描述
这个 compose 包下的 canvas interface 也没有 drawText , 不过 他含有一个 NativeCanvas

/**
 * Return an instance of the native primitive that implements the Canvas interface
 */
expect val Canvas.nativeCanvas: NativeCanvas

而 NativeCanvas 则是我们常用的canvas 的别名

actual typealias NativeCanvas = android.graphics.Canvas

写的Test ,实践一下.可行

@Composable
fun CanvasText() {
    Canvas(modifier = Modifier.fillMaxSize(), onDraw = {
        val nativePaint = android.graphics.Paint().let {
            it.apply {
                textSize = 36f
                color = android.graphics.Color.RED
            }
        }
        drawContext.canvas.nativeCanvas.drawText(
            "Jetpack Compose Draw Text",
            18f,
            size.height / 2f,
            nativePaint
        )
    })
}

另外, DrawScope 发现一个canvas 相关的内联方法,也是调用 drawContext.canvas ,所以这个方法也是可以直接.nativeCanvas 效果跟上面相通.

inline fun DrawScope.drawIntoCanvas(block: (Canvas) -> Unit) = block(drawContext.canvas)

一句话, 总结:
可在compose 包下的canvas ,.nativeCanvas 使用 之前的方法.


后来发现 androidx.compose.foundation包下的Composable的 接口Canvas
androidx.compose.ui.text 包下有一个 objectTextPainter 的下方定义了几个拓展方法 DrawScope.drawText , 至此,开启了compose式的drawText用法。
在这里插入图片描述

用法如下:

  val textMeasurer = rememberTextMeasurer()

    Canvas(modifier = Modifier.fillMaxSize()) {
        drawText(textMeasurer, "Hello")
    }

用法举例:

@Composable
fun CanvasMeasureText() {
    val pinkColor = Color(0xFFF48FB1)
    val longTextSample =
        "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum."
    
    val textMeasurer = rememberTextMeasurer()

    Spacer(
        modifier = Modifier
            .drawWithCache {
                val measuredText =
                    textMeasurer.measure(
                        AnnotatedString(longTextSample),
                        constraints = Constraints.fixedWidth((size.width * 2f / 3f).toInt()),
                        style = TextStyle(fontSize = 18.sp)
                    )

                onDrawBehind {
                    drawRect(pinkColor, size = measuredText.size.toSize())
                    drawText(measuredText)
                }
            }
            .fillMaxSize()
    ) 
}

再次瞎总结一下:
compose底层封装了 (native 可能不如View准确)View 的 Canvas,对原View体系做了一定的分类、组合、简化, 封装了paint,不需要在手动创建paint对象之类,更符合Compose用法。

拓展链接:
CanvasSnippets.kt
图形修饰符

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值