DPR DPR - 4 months ago 45
Android Question

Ellipsize not working properly for a multiline TextView with an arbitrary maximum height

I have a

TextView
with an unknown maximum height, which is dependent on the device's DPI/screen resolution. So, for instance, on and MDPI device this maximum height makes it possible to show only 2 lines at a time, a value that can be increased up to an undefined number.

My issue is related with the ellipsize functionality. Let's suppose that a certain device allows for 4 lines to be displayed. If I manually set the maximum number of lines, like this...

<TextView
android:id="@+id/some_id"
android:layout_width="fill_parent"
android:layout_height="0dip"
android:ellipsize="end"
android:maxLines="4"
android:singleLine="false"
android:layout_weight="1"
android:gravity="center_vertical"
android:text="This is some really really really really really long text"
android:textSize="15sp" />


...everything works OK. If the text doesn't fit properly, then the ellipsis are added at the end of the fourth line, like this:

This is some
really really
really really
really long...


But I'd rather not set the number of lines as a static variable, as I would prefer to include support for any combination of DPI/screen resolution. So if I remove
maxLines
the ellipsis is no longer correctly shown at line four, showing instead an incomplete portion of text:

This is some
really really
really really
really long


If I slightly increase the
TextView
size, I can see that the rest of the text is still being drawn "behind" the other
Views
. Setting the variable
maxHeight
doesn't seem to work either.

I really can't seem to find a solution for this issue. Any ideas? If it helps, I'm working only with Android v4.0.3 and up (API level 15).

Answer

Calculate how many lines fit into the TextView with TextView#getHeight() and TextView#getLineHeight(). Then call TextView#setMaxLines().

ViewTreeObserver observer = textView.getViewTreeObserver();
observer.addOnGlobalLayoutListener(new OnGlobalLayoutListener() {
    @Override
    public void onGlobalLayout() {
        int maxLines = (int) textView.getHeight()
                / textView.getLineHeight();
        textView.setMaxLines(maxLines);
        textView.getViewTreeObserver().removeGlobalOnLayoutListener(
                this);
    }
});