Search code examples
androidandroid-constraintlayout

wrap_content breaks performance of my constraint layout


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?


Solution

  • 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()
    }