Reputation: 4964
Suppose I have a single TextView
like this
As you can see, the text is broken into three lines.
Is there any way that I can get the text areas in Rects
? As this text is broken into three lines, I would need three Rects
.
It is important to highlight that the left of a Rect
is the left of the first character of the line, and the right is the right of the last character of the line.
Upvotes: 1
Views: 292
Reputation: 62831
Onik has the right idea, but the results will all be relative to zero. You will have to do a little more computation if you want to know where in the canvas the text of your TextView lies.
Here is a custom TextView that will outline the text on the screen.
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()
}
}
This is what is displayed:
You might not need this TextView, but you can grab its computations.
I find this posting very helpful when thinking about Android typography.
Upvotes: 1
Reputation: 19949
I'd do it as follows (in 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)
}
Upvotes: 1