Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Android text is cut off on a fixed height TextView

Consider this layout:

<TextView
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="160dp"
    android:textSize="20sp"
    android:text="Apple Inc. is an American multinational technology company headquartered in Cupertino, California, that designs, develops, and sells consumer electronics, computer software, and online services."
    android:ellipsize="end"
    android:gravity="top"/>

What I want the TextView to do is to figure out how many lines it can fit in 160dp and places three dots if room is not enough. However the text is cut off instead: enter image description here

How can I achieve the above behavior? I assume I can do it by just specifying some attribute on the layout resource file. Thanks.

like image 323
darklord Avatar asked Mar 25 '19 21:03

darklord


1 Answers

There's no way to achieve this by simply specifying attributes on the layout resource file.

If you look at the setEllipsize() method in TextView, you'll see that it says:

Causes words in the text that are longer than the view's width to be ellipsized instead of broken in the middle. You may also want to setSingleLine() or setHorizontallyScrolling(boolean) to constrain the text to a single line. Use null to turn off ellipsizing. If setMaxLines(int) has been used to set two or more lines, only TextUtils.TruncateAt.END and TextUtils.TruncateAt.MARQUEE are supported (other ellipsizing types will not do anything).

From that documentation, you can see that ellipsis in TextView is actually highly dependent on two factors: view width and number of lines.

As such, I recall that an ellipsis might not show up for a TextView if it doesn't know the maximum number of lines that your TextView can have.

So for your intended behavior, this isn't possible because you're depending on the View's height instead. You want to use a specific height then have a TextView calculate the amount of lines that can be shown within that height. Finally, if the amount of lines needed is greater than the amount shown, you want to show ellipses.

That's... not possible with how the ellipses in TextView is coded. It simply wasn't meant for that.

Therefore, if you want this behavior, you need to either:

  1. Create a custom TextView for your specific ellipses implementation

  2. Manually calculate the amount of lines visible, then use setMaxLines() on that TextView

For the second option, you can calculate this by using the TextView methods getHeight() and getLineHeight().

For example:

textview = (TextView) findViewById(R.id.exampleTextView);

textview.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
    @Override
    public void onGlobalLayout() {
        final int maxLines = textview.getHeight() / textview.getLineHeight();
        textview.setMaxLines(maxLines);
    }
});

In my example, I'm doing this inside a ViewTreeObserver to avoid getHeight() calling a size of 0.

The second option should be able to get the behavior you want, but if you want this for every TextView, you should consider creating a custom TextView instead.

like image 92
Jackey Avatar answered Oct 28 '22 21:10

Jackey