Check if textview is ellipsized in android
Asked Answered
P

3

22

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.

Pownall answered 22/3, 2013 at 9:50 Comment(2)
post code. tell if there are any errors. so that people better understand what you want to ask and where exactly is your problem.Anodize
Possible duplicate of How do I tell if my textview has been ellipsized?Preventer
M
68

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()

Monogenesis answered 22/3, 2013 at 10:2 Comment(9)
Just a method call on your textview. Added code. (not tested)Monogenesis
if I use "setText",then textview1.getLayout()==null.Transformer
That must mean that your textview isn't created yet, or has been under some changes as the doc says. You can wait for the view to be ready again, by using textview1.post(new Runnable{});Marmara
the getEllipsisCount() method has an int paramter . update your answer ;)Fidole
@Monogenesis : i've edited your answer with the correct implementation of ellipsize test ;)Fidole
Use a runnable if your getLayout() returns null.Denti
@Monogenesis layout.getEllipsisCount(lines-1) is returning 0 when string value is too large like approx 8000-9000 charactersTransitory
Directly its not working but when i used this code in runnable its working like charm.Societal
This method is not reliable if the text just meet the ellipsis truncate condition. e.g (Clear cache -> Clear cac..., the API android.text.Layout#getEllipsisCount always return 0 event if the TextView is displaying ellipsis.Rihana
B
15

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) {
    // Check if the supplied TextView is not null
    if (textView == null) {
        return false;
    }

    // Check if ellipsizing the text is enabled
    final TextUtils.TruncateAt truncateAt = textView.getEllipsize();
    if (truncateAt == null || TextUtils.TruncateAt.MARQUEE.equals(truncateAt)) {
        return false;
    }

    // Retrieve the layout in which the text is rendered
    final Layout layout = textView.getLayout();
    if (layout == null) {
        return false;
    }

    // Iterate all lines to search for ellipsized text
    for (int line = 0; line < layout.getLineCount(); ++line) {

        // Check if characters have been ellipsized away within this line of text
        if (layout.getEllipsisCount(line) > 0) {
            return true;
        }
    }

    return false;
}

There is still room for improvement, though. But this method does suffice my use cases. Corrections and improvements are appreciated. :-)

Bradybradycardia answered 3/11, 2015 at 12:23 Comment(0)
D
2

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.

Denticulate answered 14/2, 2015 at 17:24 Comment(1)
I assume m.isEllipsized is just a flag set on the class that contains the code block in the exampleIntrastate

© 2022 - 2024 — McMap. All rights reserved.