从 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
包下有一个 object
的TextPainter
的下方定义了几个拓展方法 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
图形修饰符