Android TextView does not hug text tightly with multiple lines, sticks to maxWidth instead

238 views Asked by At

I am creating a chat bubble and I noticed that when you have a TextView with text that spans multiple lines the width of the box locks to the (in this case) maxWidth. This may cause a gap on the right side:

    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:maxWidth="100dp"
        android:padding="4dp"
        android:text="this is a pretty short sentence"/>

big right gap

As you can see there is a big white gap on the right. Without the maxWidth it fits on one line and it fits snugly:

snug fit

How do I make it so that when the text spans multiple lines the box still tightly hugs the text? I've tried lots of things, but is this even possible?

Desired result:

desired result

update:

android:justificationMode="inter_word"

Results in the text fitting the box instead of the box fitting the text, which is way uglier:

inter_word t

2

There are 2 answers

0
Janneman On BEST ANSWER

Turns out it's easy to fix by subclassing TextView and overriding onMeasure(). It even works in the Layout Editor. Also performance is no issue at all:

@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
    //call super first so you can call getLineCount(), getLineMax()) and getMeasuredHeight() below
    super.onMeasure(widthMeasureSpec, heightMeasureSpec);

    //if more than 1 line set width equal to that of the largest line
    int lineCount = getLayout().getLineCount();
    if (lineCount > 1) {
        //get the width of the largest line
        float lineWidth = 0;
        for (int i = 0; i < lineCount; i++) {
            lineWidth = Math.max(lineWidth, getLayout().getLineMax(i));
        }
        //set largest line width + horizontal padding as width and keep the height the same
        setMeasuredDimension((int) Math.ceil(lineWidth) + getPaddingLeft() + getPaddingRight(), getMeasuredHeight());
    }
}
1
Nguyễn Tư On

in TextView XML, you can use:

android:justificationMode="inter_word"