You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Kotlin中使用Canvas.drawText绘制PDF长文本如何实现换行

Canvas.drawText 实现换行(Kotlin)

问题背景

使用canvas.drawText()向PDF写入文本时,从string.xml获取的长文本(存储在nameSpeech变量)无法自动换行,\n转义字符也不生效,需仅通过drawText()实现换行效果。

可行方案:手动拆分文本逐行绘制

canvas.drawText()本身不支持自动解析换行符或自动换行,但可以通过手动拆分文本为多行,再逐行调用drawText()实现需求,具体步骤如下:

1. 拆分文本为多行

两种拆分方式,按需选择:

  • 方式一:按已有换行符拆分
    如果文本本身包含\n,直接用split()分割:

    val fullText = "This was his speech: $nameSpeech"
    val lines = fullText.split("\n")
    
  • 方式二:根据画布宽度自动拆分长文本
    对于无换行符的连续长文本,用StaticLayout自动计算每行可容纳的内容:

    fun splitTextToFitWidth(text: String, paint: Paint, maxWidth: Float): List<String> {
        val lineList = mutableListOf<String>()
        val layout = StaticLayout.Builder.obtain(text, 0, text.length, paint, maxWidth.toInt())
            .build()
        for (i in 0 until layout.lineCount) {
            val startIndex = layout.getLineStart(i)
            val endIndex = layout.getLineEnd(i)
            lineList.add(text.substring(startIndex, endIndex))
        }
        return lineList
    }
    
    // 使用示例:画布左右留20F边距
    val maxLineWidth = canvas.width - 40F
    val lines = splitTextToFitWidth("This was his speech: $nameSpeech", title, maxLineWidth)
    

2. 逐行绘制文本

设置行高后,循环绘制每一行:

var currentY = 200F // 初始Y坐标
val lineSpacing = title.fontSpacing // 系统计算的字体行高,也可手动设置固定值(如30F)

lines.forEach { line ->
    canvas.drawText(line, 20F, currentY, title)
    currentY += lineSpacing
}

关键提示

  • canvas.drawText()不会处理\n,必须手动拆分文本后逐行绘制
  • StaticLayout是Android提供的工具类,能自动适配宽度拆分文本,适合处理无换行的长内容
  • Kotlin实现逻辑和Java一致,只是语法更简洁,比如使用Lambda循环、可变列表等特性

内容的提问来源于stack exchange,提问作者Adx

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.11 19:55:19