是否可以获取 TextView 的文本 Rects?
Is it possible to get the text Rects of a TextView?
假设我有一个这样的TextView
如您所见,文本分为三行。
有什么方法可以获取 Rects
? As this text is broken into three lines, I would need three Rects
中的文本区域。
需要强调的是,a Rect
的左边是该行第一个字符的左边,右边是该行最后一个字符的右边。
我会按如下方式进行(在 Kotlin 中):
var lineStart = 0
var lineEnd = 0
var lineText = ""
val paint = textView.paint
val rectList = arrayListOf<Rect>()
for (i in 0 until textView.lineCount) {
lineStart = textView.layout.getLineStart(i)
lineEnd = textView.layout.getLineEnd(i)
lineText = textView.text.substring(lineStart, lineEnd)
val rect = Rect()
paint.getTextBounds(lineText, 0, lineText.length - 1, rect)
rectList.add(rect)
}
Onik 的想法是对的,但结果都是相对于零的。如果您想知道 TextView 的文本在 canvas 中的什么位置,您将需要做更多的计算。
这是一个自定义 TextView,它将在屏幕上显示文本轮廓。
class CustomTextView @JvmOverloads constructor(
context: Context, attrs: AttributeSet? = null, defStyleAttr: Int = android.R.attr.textViewStyle
) : AppCompatTextView(context, attrs, defStyleAttr) {
private val mPaint = Paint().apply {
strokeWidth = 2f
style = Paint.Style.STROKE
color = Color.RED
}
private val mLineOutline = Rect()
override fun onDraw(canvas: Canvas) {
super.onDraw(canvas)
canvas.save()
// This is the view's padding which we want to ignore.
canvas.translate(totalPaddingLeft.toFloat(), totalPaddingTop.toFloat())
for (line in 0 until lineCount) {
// This gets the outline of the text on a line but it is all relative to zero.
paint.getTextBounds(
text.toString(), layout.getLineStart(line), layout.getLineEnd(line), mLineOutline
)
canvas.save()
// We have the outline relative to zero, shift it so it outlines the text.
canvas.translate(layout.getLineLeft(line), layout.getLineBaseline(line).toFloat())
canvas.drawRect(mLineOutline, mPaint)
canvas.restore()
}
canvas.restore()
}
}
这是显示的内容:
你可能不需要这个 TextView,但你可以获取它的计算。
我发现 this 在思考 Android 排版时发帖很有帮助。
假设我有一个这样的TextView
如您所见,文本分为三行。
有什么方法可以获取 Rects
? As this text is broken into three lines, I would need three Rects
中的文本区域。
需要强调的是,a Rect
的左边是该行第一个字符的左边,右边是该行最后一个字符的右边。
我会按如下方式进行(在 Kotlin 中):
var lineStart = 0
var lineEnd = 0
var lineText = ""
val paint = textView.paint
val rectList = arrayListOf<Rect>()
for (i in 0 until textView.lineCount) {
lineStart = textView.layout.getLineStart(i)
lineEnd = textView.layout.getLineEnd(i)
lineText = textView.text.substring(lineStart, lineEnd)
val rect = Rect()
paint.getTextBounds(lineText, 0, lineText.length - 1, rect)
rectList.add(rect)
}
Onik 的想法是对的,但结果都是相对于零的。如果您想知道 TextView 的文本在 canvas 中的什么位置,您将需要做更多的计算。
这是一个自定义 TextView,它将在屏幕上显示文本轮廓。
class CustomTextView @JvmOverloads constructor(
context: Context, attrs: AttributeSet? = null, defStyleAttr: Int = android.R.attr.textViewStyle
) : AppCompatTextView(context, attrs, defStyleAttr) {
private val mPaint = Paint().apply {
strokeWidth = 2f
style = Paint.Style.STROKE
color = Color.RED
}
private val mLineOutline = Rect()
override fun onDraw(canvas: Canvas) {
super.onDraw(canvas)
canvas.save()
// This is the view's padding which we want to ignore.
canvas.translate(totalPaddingLeft.toFloat(), totalPaddingTop.toFloat())
for (line in 0 until lineCount) {
// This gets the outline of the text on a line but it is all relative to zero.
paint.getTextBounds(
text.toString(), layout.getLineStart(line), layout.getLineEnd(line), mLineOutline
)
canvas.save()
// We have the outline relative to zero, shift it so it outlines the text.
canvas.translate(layout.getLineLeft(line), layout.getLineBaseline(line).toFloat())
canvas.drawRect(mLineOutline, mPaint)
canvas.restore()
}
canvas.restore()
}
}
这是显示的内容:
你可能不需要这个 TextView,但你可以获取它的计算。
我发现 this 在思考 Android 排版时发帖很有帮助。