I have a single TextView
which I am updating as a counter every second. If I use wrap_content
for its width, I get performance warnings that it takes 50ms to draw the view update in the layout/measure phase. When I programmatically set its width and height, it addresses the alerts, but my views no longer resize (obviously :). What am I missing here? Is there way to minimize view invalidations / resizing to be only when the text changes to a greater width? Do I have to do that programmatically and calculate the new size each time I update the view?
This is not really a solution to why it was happening in the first place, but a workout around (Which feels very anti-android since it doesn't rely on ConstraintLayout to solve what hopefully is a simple system of equations to determine the proper intrinsic TextView width without breaking the whole UI thread):
fun TextView.conditionallyChangeWidthWithNewString(newString: CharSequence) {
val calculatedWidth = getWidthOfNewText(newString.toString())
if (calculatedWidth > layoutParams.width) {
val params = getLayoutParams()
params.width = calculatedWidth
setLayoutParams(params)
}
setTextIfChanged(newString)
}
fun TextView.getWidthOfNewText(s: String): Int {
val p = Paint()
val bounds = Rect()
val plain = typeface
p.setTypeface(plain)
p.textSize = textSize
p.getTextBounds(s, 0, s.length, bounds)
val mt = p.measureText(s)
return mt.toInt()
}