Android 中的 Paint 和 TextPaint 有什么区别?

What is the difference between Paint and TextPaint in Android?

PaintTextPaint 有什么区别?只能 TextPaint 将文本绘制到 canvas?

我最近一直在研究如何在 canvas 上绘制文本,这让我想到了 TextPaint。然而,在阅读 the source code 时,我惊讶地发现 TextPaint 根本没有太多内容。事实上,您实际上并不需要它在 canvas 上绘制文本。所以我添加了这个问答以使其更清楚。

TextPaint is a subclass of Paint。然而,与您从这些名称中可能猜到的相反,在 canvas 上绘制文本的繁重工作是由 Paint 完成的。因此,这

TextPaint textPaint = new TextPaint();
textPaint.setTextSize(50);
canvas.drawText("some text", 10, 100, textPaint);

还有这个

Paint paint = new Paint();
paint.setTextSize(50);
canvas.drawText("some text", 10, 100, paint);

实际上做同样的事情。 TextPaint 只是 Paint 的轻量级包装,并给 Android 一些 extra data to work with when drawing and measuring text. You can see this in action if you read the TextLine class source code (this class draws a line of text). This is apparently why you have to pass in a TextPaint and not a Paint object when creating something like a StaticLayout

TextPaint 字段

关于 "extra data" 的内容的文档非常少,这里有更全面的解释。 (Disclamer:通过在 TextPaint 中更改这些值,我实际上无法影响测试中文本绘制方式的任何更改。所以采取这部分有保留意见。)

  • baselineShift - The baseline is the line at the base of the text. See this answer 一张图片。更改 baselineShift 会导致基线向上或向下移动,从而影响文本在一行中的绘制高度。
  • bgColor - 这是文本后面的背景色。
  • density - 我假设这是屏幕密度,但我找不到任何源代码中使用它。
  • drawableState - I couldn't find much in the source code except a PFLAG_DRAWABLE_STATE_DIRTY标志,这让我觉得这是用来让对象知道什么时候需要重绘的。
  • linkColor - 我只能假设这意味着它所说的,link 的文本颜色。但是,我找不到在任何源代码中使用它。

备注

稍微翻了一下源码,发现public参数如baselineShift实际上是NOT应用于canvas时您使用 textPaint 作为参数调用 drawText,但 TextPaint 保存了一个额外的数据供您检索以手动应用于绘图操作。

比如我想让(0, 0)作为我画的文字的中心位置,我通常就是这样。

例子

private val mTextPaint = TextPaint().apply {
    color = Colors.BLACK
    textSize = 14.sp
    isAntiAlias = true
    baselineShift = (textSize / 2 - descent()).toInt()
    textAlign = Paint.Align.CENTER
}
override fun onDraw(canvas: Canvas) {
    super.onDraw(canvas)
    canvas.drawText("Hello World", 0f, mTextPaint.baselineShift.toFloat(), mTextPaint)
}

注: sp是kotlin中的扩展属性,作用类似于函数sp2px(Number sp)
,而(textSize / 2 - descent()).toInt() 可能不是最准确的使文本居中的方法,如果您有更好的方法,请发表评论。