根据文本边界将 TextView 放置在容器的中心

Place TextView in center of container based on text bounds

我正在尝试以编程方式将 TextView 放置在其容器的中心,其中仅考虑文本边界,而不考虑整个 TextView 矩形。 见下图:

还有我的代码:

// "workingLayout" is the container on the TextView
val tvv = TextView(this)
tvv.includeFontPadding = false
tvv.setPadding(20, 0, 20, 0)
tvv.gravity = Gravity.CENTER
tvv.text = "ggg"
tvv.setTextSize(TypedValue.COMPLEX_UNIT_SP, 150f)
tvv.setTextColor(Color.BLUE)
tvv.background = resources.getDrawable(R.drawable.edit_text_shape, null)

tvv.measure(View.MeasureSpec.UNSPECIFIED, View.MeasureSpec.UNSPECIFIED)
tvv.x = (workingLayout.width / 2f) - (tvv.measuredWidth / 2)
tvv.y = (workingLayout.height / 2f) - (tvv.measuredHeight / 2)
workingLayout.addView(tvv)

我尝试使用 paint.getTextBounds 而不是 measure 但没有成功...

谢谢!

感谢 this post。

基本上,paint.getTextBounds 结果是相对于 TextView baseline,我们可以从 textView.baseline 得到的 TextView 基线,假设我们可以计算文本边界框的中点,并且从容器中点减去那个(而不是 TextView 中点)。

参考图:

val tv = TextView(this)
// init TextView
...
...
tv.measure(View.MeasureSpec.UNSPECIFIED, View.MeasureSpec.UNSPECIFIED)

// Get text bounding box
val bbox = Rect()
tv.paint.getTextBounds(tv.text.toString(), 0, tv.text.toString().length, bbox)

// The distance from textview top to actual text top
val textInsetTop = tv.baseline + bbox.top

// Text bounding box mid
val bboxMid = textInsetTop + (bbox.height() / 2f)

// Now can center the TextView in its container
val containerMid = workingLayout.height / 2f
tv.y = containerMid - bboxMid

重要提示:这仅适用于单行文本视图(和非缩放)。