StaticLayout超出界限

时间:2019-02-21 16:00:42

标签: android staticlayout

我创建一个StaticLayout并将其绘制到画布上。我有一个Rect区域,需要在其中填充文本,因此我关注以下内容:

  1. 我计算文字大小以适合给定范围
  2. 我使用计算出的文字大小创建一个StaticLayout
  3. 我将StaticLayout绘制到画布上

问题

即使StaticLayout.widthStaticLayout.height都适合我的矩形,但文本与矩形重叠。怎么会这样?

屏幕截图显示,文本超出了左右两侧的矩形范围(您可以在A处看到它很好)

日志行

//Information: the uncleaned text is "A\nP\nP\nS" => as I want vertical text in this case
TextSize: 55.75 | Apps | rect: 24x481 | layout rect: 18x471 | offsets: 3.0, 5.0 

// as you see, the staticlayout's rect is SMALLER then the rect it should fit in
// so it should no overlay anywhere...

SCREENSHOT

在这里,您将看到视图的外观(这是属于上面的日志行的屏幕截图):

enter image description here

代码

private lateinit var paint: Paint
private lateinit var textPaint: TextPaint

override fun onDraw(canvas: Canvas) {
    super.onDraw(canvas)

    val rect: Rect = ... // the target rectangle for my text

    // 1) Draw the rectangle (the background of the text)
    canvas.drawRect(
        rect,
        paint
    )

    // 2) prepare text
    val text: String = ... // some text that should be drawn WITHIN the rectangle
    val textColor: Int = ... // some text color
    val textSize: Float = ... // value is calculated in a helper class of mine
    val textPadding = 0f

    val staticLayout = getStaticLayout(text, textPaint, rect.width() - 2 * textPadding)
    val offsetX = (rect.width() - staticLayout.width) / 2f
    val offsetY = (rect.height() - staticLayout.height) / 2f

    textPaint.color = textColor
    textPaint.textSize = textSize

    // 3) draw text
    canvas.save()
    canvas.translate(rect.left.toFloat() + offsetX, rect.top.toFloat() + offsetY)
    staticLayout.draw(canvas)
    canvas.restore()

    // Test logging to verify the problem
    L.d { "TextSize: ${textSize}" +
            " | ${text.text.filter { it != '\n' }}" + // strip out new lines for a cleaner log
            " | rect: ${rect.width()}x${rect.height()}" +
            " | layout rect: ${staticLayout.width}x${staticLayout.height}" +
            " | offsets: $offsetX, $offsetY" }
    }
}

// helper function
fun getStaticLayout(text: CharSequence, paint: TextPaint, width: Int): StaticLayout {

    val spacingMult = 1f
    val spacingAdd = 0f
    val includePadding = true
    val alignment = Layout.Alignment.ALIGN_CENTER

    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
        return StaticLayout.Builder.obtain(text, 0, text.length, paint, width)
                .setAlignment(alignment)
                .setLineSpacing(spacingAdd, spacingMult)
                .setIncludePad(includePadding)
                .build()
    } else {
        @Suppress("DEPRECATION")
        return StaticLayout(
                text,
                0,
                text.length,
                paint,
                width,
                alignment,
                spacingMult,
                spacingAdd,
                includePadding
        )
    }
}

0 个答案:

没有答案