I have TextView
with width as wrap content
. In this TextView
I set text, but text is not of the same length every time. When text is very long I use single line true and ellipsize
: end. But now I have a problem. I want to set Visibility of other layout but that depends on the length my text. If text is too long to fit in the screen I want to setVisible true, but when text is short and when I don't need ellipsize, I want to set visibility false. So I need to check status of my TextView. When its ellipsize I want to setVisible
true, when its not setVisible
false. How I can do that.
This is what I got:
tvAle.post(new Runnable() {
@Override
public void run() {
int lineCount = tvAle.getLineCount();
Paint paint = new Paint();
paint.setTextSize(tvAle.getTextSize());
final float size = paint.measureText(tvAle.getText().toString());
Log.v("a", ""+size+" "+tvAle.getWidth());
if ((int)size > (tvAle.getWidth()+10)) {
allergiesLayout.setVisibility(View.VISIBLE);
}
else
allergiesLayout.setVisibility(View.GONE);
}
but this solution doesn't work.
You can use this method provided: getEllipsisCount
Layout layout = textview1.getLayout();
if(layout != null) {
int lines = layout.getLineCount();
if(lines > 0) {
int ellipsisCount = layout.getEllipsisCount(lines-1);
if ( ellipsisCount > 0) {
Log.d(TAG, "Text is ellipsized");
}
}
}
where line could be obtained via getLineCount()
Well, the accepted solution does work but misses a few corner cases because it will only check the last line for ellipsized characters. If we have a TextView consisting of two lines and use TruncateAt.START to truncate the text at its beginning, the accepted answer will fail. :-/
Adding an ViewTreeObserver.OnPreDrawListener seems more like a really expensive overhead to me. So I made the following improvements to the code of the accepted answer:
/**
* Checks if the text of the supplied {@link TextView} has been ellipsized.
*
* @param textView
* The {@link TextView} to check its text.
*
* @return {@code True} if the text of the supplied {@code textView} has been ellipsized.
*/
public static boolean isTextViewEllipsized(final TextView textView) {
// Initialize the resulting variable
boolean result = false;
// Check if the supplied TextView is not null
if (textView != null) {
// Check if ellipsizing the text is enabled
final TextUtils.TruncateAt truncateAt = textView.getEllipsize();
if (truncateAt != null && !TextUtils.TruncateAt.MARQUEE.equals(truncateAt)) {
// Retrieve the layout in which the text is rendered
final Layout layout = textView.getLayout();
if (layout != null) {
// Iterate all lines to search for ellipsized text
for (int index = 0; index < layout.getLineCount(); ++index) {
// Check if characters have been ellipsized away within this line of text
result = layout.getEllipsisCount(index) > 0;
// Stop looping if the ellipsis character has been found
if (result) {
break;
}
}
}
}
}
return result;
}
There is still room for improvement, though. But this method does suffice my use cases. Corrections and improvements are appreciated. :-)
Using getEllipsisCount wont work with text that has empty lines within it. I used the following code to make it work :
message.getViewTreeObserver().addOnPreDrawListener(new ViewTreeObserver.OnPreDrawListener() {
@Override
public boolean onPreDraw() {
if(m.isEllipsized == -1) {
Layout l = message.getLayout();
if (message.getLineCount() > 5) {
m.isEllipsized = 1;
message.setMaxLines(5);
return false;
} else {
m.isEllipsized = 0;
}
}
return true;
}
});
Make sure not to set a maxLineCount in your XML. Then you can check for the lineCount in your code and if it is greater than a certain number, you can return false to cancel the drawing of the TextView and set the line count as well as a flag to save whether the textView is too long or not. The textview will draw again with the correct line count and you will know whether its ellipsized or not with the flag.
You can then use the isEllipsized flag to do whatever you require.