You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
this code doesn't consider that the text is not justified. So every end of line will take spaces, which will be reported on the last line. So the ellipsis can be ellipsed it self by TextView.
Example :
Based on your solution, I wrote this version of EllipsizedTextView which fix previously mentioned issues.
I reused TextUtils.ellipsize() but only on the last line retrieved from the layout, to avoid issue 3.
Also, instead of using overriding onMeasure(), I overridden onLayout()
Note : Only Ellipsize end is handled.
classEllipsizedTextView @JvmOverloads constructor(context:Context, attrs:AttributeSet? = null, defStyleAttr:Int = 0) : AppCompatTextView(context, attrs, defStyleAttr) {
privatevar ellipsis = getDefaultEllipsis().toString()
privatevar ellipsisColor = getDefaultEllipsisColor()
privateval ellipsisSpannable:SpannableStringprivateval spannableStringBuilder =SpannableStringBuilder()
init {
if (ellipsize !=TextUtils.TruncateAt.END) {
throw java.lang.IllegalStateException("Only end ellipsize is handled.")
}
if (attrs !=null) {
val typedArray = context.theme.obtainStyledAttributes(attrs, R.styleable.EllipsizedTextView, 0, 0)
ellipsis = typedArray.getString(R.styleable.EllipsizedTextView_ellipsis) ?: getDefaultEllipsis().toString()
ellipsisColor = typedArray.getColor(R.styleable.EllipsizedTextView_ellipsisColor, getDefaultEllipsisColor())
typedArray.recycle()
}
ellipsisSpannable =SpannableString(ellipsis)
ellipsisSpannable.setSpan(ForegroundColorSpan(ellipsisColor), 0, ellipsis.length, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE)
}
overridefunonLayout(changed:Boolean, left:Int, top:Int, right:Int, bottom:Int) {
super.onLayout(changed, left, top, right, bottom)
if (changed && layout.lineCount >= maxLines) {
val lastLineNb = maxLines -1val ellipsisCount = layout.getEllipsisCount(lastLineNb)
if (ellipsisCount >0) {
val availableScreenWidth = measuredWidth - compoundPaddingLeft.toFloat() - compoundPaddingRight.toFloat()
val lastLineAvailableTextWidth = availableScreenWidth - paint.measureText(ellipsis)
val lastLineStart = layout.getLineStart(lastLineNb)
val lastLineEnd = layout.getLineEnd(lastLineNb)
val textWithoutLastLine = text.subSequence(0, lastLineStart)
val lastLineText = text.subSequence(lastLineStart, lastLineEnd)
val ellipsizedLasLine =TextUtils.ellipsize(lastLineText, paint, lastLineAvailableTextWidth, ellipsize)
spannableStringBuilder.clear()
val result = spannableStringBuilder.append(textWithoutLastLine).append(ellipsizedLasLine).append(ellipsisSpannable)
text = result
}
}
}
privatefungetDefaultEllipsis(): Char {
returnTypography.ellipsis
}
privatefungetDefaultEllipsisColor(): Int {
return textColors.defaultColor
}
funisEllipsized(): Boolean {
if (TextUtils.isEmpty(text) || text.length < ellipsis.length) {
returnfalse
}
val finalWord = text.subSequence(text.length - ellipsis.length, text.length)
returnTextUtils.equals(finalWord, ellipsis)
}
}
I didn't opened a pull request, since the project is not building with latest Android Studio.
I still share my solution it may help other.
The text was updated successfully, but these errors were encountered:
it's recycled overtime when I use RecyclerView, it won't showing the ellipsis again @Loic-Dumas
And since you use onLayout instead of onMeasure, does it will degrade the performance?
Hello @jboxx,
In my use case, I don't use RecyclerView and haven't tested on it.
After some time in production, I didn't noticed degradation in app performance using onLayout().
But if maybe it's better to still do the ellipsize in onMeasure().
The code can be easily shift to this overridden method.
I noticed multiple issues with the
1.0.0
implementation.If the text contains "...", before the final ellipsis, the custom ellipsis is added in the text, not at the end.
Example :
As mentioned in issue Not working 100% #1
maxLines should only apply to the
availableScreenWidth
and not the ellipsis width. So the line should be :Otherwise, the more line there is, the ellispis will be more distant to the end of last line.
ellipsizedText
is computed withTextUtils.ellipsize(...)
works only on single line. With multiple line, when computing.this code doesn't consider that the text is not justified. So every end of line will take spaces, which will be reported on the last line. So the ellipsis can be ellipsed it self by TextView.
Example :
Based on your solution, I wrote this version of
EllipsizedTextView
which fix previously mentioned issues.I reused
TextUtils.ellipsize()
but only on the last line retrieved from the layout, to avoid issue 3.Also, instead of using overriding
onMeasure()
, I overriddenonLayout()
Note : Only Ellipsize end is handled.
I didn't opened a pull request, since the project is not building with latest Android Studio.
I still share my solution it may help other.
The text was updated successfully, but these errors were encountered: