Reputation: 766
I'm trying to set ellipsis to the end of my text(multi-line) if the text is too long.
I already know I can use setMaxLines()
and setEllipsize()
to achieve the effect. However, since my textview's size is dynamically changeable, I don't know the max number of lines that can be displayed. Instead I have the textview's height (by pixel).
How do I set ellipsis based on the height of the view and the text(includes font properties)? If no direct available resource I can use, what could be the easiest possible approach?
Upvotes: 3
Views: 1598
Reputation: 786
I have implemented that using the concept of this answer.
You can create an extension function like this-
/**
* Calculate max lines according height
*
* @param text- text need to be set
* @param lineCount- invoked with -1 if view height is enough to show full text,
* otherwise invoked with maxLines
*/
inline fun TextView.calculateMaxLines(text: String, crossinline lineCount: (Int) -> (Unit)) {
val params: PrecomputedTextCompat.Params = TextViewCompat.getTextMetricsParams(this)
val ref: WeakReference<TextView>? = WeakReference(this)
GlobalScope.launch(Dispatchers.Default) {
val computedText = PrecomputedTextCompat.create(text, params)
ref?.get()?.apply {
TextViewCompat.setPrecomputedText(this, computedText)
GlobalScope.launch(Dispatchers.Main) {
ref.get()?.let {
val bounds = it.getLineBounds(0, null)
val heightRequired = bounds * it.lineCount
val maxLines = if (heightRequired > height) {
height / bounds
} else -1
lineCount.invoke(maxLines)
}
}
}
}
}
Then you can call it and set maxLines like this-
textView.calculateMaxLines("Line 1\nLine2\nLine3\nLine4\nLine5\nLine6\nLine7\nLine8") {
if (it >= 0) {
tvUserName.maxLines = it
tvUserName.ellipsize = TextUtils.TruncateAt.END
}
}
Or, for Java you can call it like this-
ExtensionsKt.calculateMaxLines(textView, text, maxLines -> {
if (maxLines >= 0) {
textView.setMaxLines(maxLines);
textView.setEllipsize(TextUtils.TruncateAt.END);
}
return null;
});
Upvotes: 0
Reputation: 11028
You can use getLineCount()
(but only after a layout pass).
See this answer for more information.
Upvotes: 2