Fred Porciúncula
Fred Porciúncula

Reputation: 8902

Android autosizing TextViews split up words before decreasing font size

Is there a way to avoid it?

If my text is "Blablabla" and it doesn't fit in a square, I don't want to have something like:

Blabla- bla

I want "Blablabla" with a smaller font size. Is there a way to control whether the autosizing TextView will split up words or not?

Here's an example of the issue:

enter image description here

The minimum text size there is 1sp, so it's pretty clear the word could fit with a decreased text size.

It seems this has been reported: https://issuetracker.google.com/issues/38468964

Upvotes: 16

Views: 5184

Answers (5)

Ganso Doido
Ganso Doido

Reputation: 607

I hope this gives someone a better idea.

Basically, we force AutoSizing feature to use a single line to measure the text, so it will be forced to use minimum text size.

Then after the measure is done, we allow it to use more lines if it needs.

public static void setTextForAutoSizingUsingMinimumLines(final TextView textView, final String text) {
textView.setMaxLines(1);
textView.setText(text);

textView.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
    @Override
    public void onGlobalLayout() {
        Layout layout = textView.getLayout();
        if (layout == null) {
            return;
        }

        textView.getViewTreeObserver().removeOnGlobalLayoutListener(this);
        if (layout.getLineCount() > textView.getMaxLines()) {
            //Let TextView use as much lines Layout needs to display text.
            textView.setMaxLines(layout.getLineCount());
            textView.invalidate();
        }
    }
});

}

Upvotes: 1

android developer
android developer

Reputation: 116392

I've actually reported about this issue in the past (here and here, one you've already found out about), but it seems there is a solution, or at least it seems to work for me.

I think the tip could help:

enter image description here

This means you can choose the break strategy for the textView. Example:

<TextView
   android:layout_width="250dp" 
   android:layout_height="wrap_content" 
   android:background="#f00"
   android:breakStrategy="balanced" 
   android:hyphenationFrequency="none"
   android:text="This is an example text" 
   android:textSize="30dp" 
   app:autoSizeTextType="uniform"/>

Sadly, this doesn't always seem to work nicely as it should. I've noticed that on Hebrew, it sometimes doesn't get spread well:

https://issuetracker.google.com/issues/79936443

But at least it won't put part-words for no reason.

The major disadvantage of using this solution, is that it's available only from API 23 (at least 62% of the devices, according to Android dashboard statistics). Someone has asked it to be on the support library (here), but was told it's impossible.

Upvotes: 6

Eric B.
Eric B.

Reputation: 703

I came here having the same issues with two-line text as others. The only thing that works for me is this: https://github.com/AndroidDeveloperLB/AutoFitTextView

It's not as convenient as adding a couple lines to your layout, but it works in situations where Android's auto size doesn't.

Upvotes: 1

Michael Walton
Michael Walton

Reputation: 411

I had a similar issue on a button with Android autotextsizing the string "Reading lists" over two lines as "Readin" and "g lists".

The only successful workaround I could find was to replace the blank space between the words with a line-feed ("\n"). So the string resource became:

<string name="textButtonReadingLists">Reading\nlists</string>

Not ideal, but Android put "Reading" on one line and "lists" below it. Hope that helps someone else.

Upvotes: 0

Nicola Salvaro
Nicola Salvaro

Reputation: 565

I had the same problem and found a "precarious" work around. For me it works because the text I needed to put in the textView was only one or two words... Anyway, I hope it helps or, at least, it gives you some inspiration. Here's what i did:

in XML I added android:maxLines="2" to the AppCompatTextView.

in code I checked if the text was only ONE word and, if so, set programmatically textView.setMaxLines(1);

I understand it not a perfect nor a universal solution but was good enough for me. Anyway... if you only need to scale "Blablabla" properly using android:maxLines="1" should do the trick.

Upvotes: 3

Related Questions