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).
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);
}
});
The accepted answer works well up to API 27. However, since API 28, if the line height was not set (by one of the follow methods), by default Android adds extra spacing between lines, but not after the last line.
android:lineHeight=...
(documentation) in your layout XMLtextView.setLineHeight(...)
in your source code.To find out the new line height for API 28 and above, I used textView.getLineBounds()
.
Kotlin
val observer = textView?.viewTreeObserver
observer?.addOnGlobalLayoutListener(object : ViewTreeObserver.OnGlobalLayoutListener {
override fun onGlobalLayout() {
textView?.let { view ->
val lineHeight: Int
lineHeight = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) {
val bounds = Rect()
textView.getLineBounds(0, bounds)
bounds.bottom - bounds.top
} else {
textView.lineHeight
}
val maxLines = textView.height / lineHeight
textView.maxLines = maxLines
textView.viewTreeObserver.removeOnGlobalLayoutListener(this)
}
}
})
Android Java
ViewTreeObserver observer = textView.getViewTreeObserver();
observer.addOnGlobalLayoutListener(new OnGlobalLayoutListener() {
@Override
public void onGlobalLayout() {
int lineHeight = textView.getLineHeight();
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) {
Rect bounds = new Rect();
textView.getLineBounds(0, bounds);
lineHeight = bounds.bottom - bounds.top;
}
int maxLines = (int) textView.getHeight() / lineHeight;
textView.setMaxLines(maxLines);
textView.getViewTreeObserver().removeGlobalOnLayoutListener(
this);
}
});
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With