在android中检查textview是否为椭圆形。

时间:2021-06-01 16:58:12

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:

我有TextView,宽度为wrap内容。在这个TextView中,我设置了文本,但是文本的长度不是每次都相同。当文本很长时,我使用单行true和椭圆:end。但现在我有一个问题。我想要设置其他布局的可见性,但这取决于文本的长度。如果文本太长,不能适应屏幕,我想设置为true,但是当文本很短,当我不需要椭圆时,我想设置可见性错误。所以我需要检查我的TextView的状态。当它的椭圆大小我想要setVisible true,当它不是setVisible false。我怎么能做到。这就是我得到的:

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.

但这个办法行不通。

3 个解决方案

#1


45  

You can use this method provided: getEllipsisCount

您可以使用此方法提供:get椭面。

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

可以通过getLineCount()获得行

#2


8  

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. :-/

好的,被接受的解决方案确实有效,但是忽略了一些角落的情况,因为它只会检查最后一行的椭圆形字符。如果我们有一个包含两条线的TextView,并使用TruncateAt。在开始截断文本时,被接受的答案将会失败。:- /

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:

添加一个ViewTreeObserver。对我来说,OnPreDrawListener似乎更像是一个昂贵的开销。因此,我对被接受的答案的代码做了如下改进:

/**
 * 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. :-)

不过,仍有改进的余地。但是这个方法可以满足我的用例。更正和改进是值得赞赏的。:-)

#3


1  

Using getEllipsisCount wont work with text that has empty lines within it. I used the following code to make it work :

使用get椭圆体将不会使用在其内部有空行的文本。我使用以下代码使其工作:

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.

确保不要在XML中设置maxLineCount。然后,您可以在代码中检查lineCount,如果它大于某个数字,您可以返回false来取消TextView的绘制,并设置行数和标志,以保存TextView是否太长。textview将使用正确的行计数再次绘制,您将知道它的大小是否为椭圆形。

You can then use the isEllipsized flag to do whatever you require.

然后,您可以使用is椭圆大小的标志来执行您需要的任何操作。

#1


45  

You can use this method provided: getEllipsisCount

您可以使用此方法提供:get椭面。

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

可以通过getLineCount()获得行

#2


8  

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. :-/

好的,被接受的解决方案确实有效,但是忽略了一些角落的情况,因为它只会检查最后一行的椭圆形字符。如果我们有一个包含两条线的TextView,并使用TruncateAt。在开始截断文本时,被接受的答案将会失败。:- /

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:

添加一个ViewTreeObserver。对我来说,OnPreDrawListener似乎更像是一个昂贵的开销。因此,我对被接受的答案的代码做了如下改进:

/**
 * 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. :-)

不过,仍有改进的余地。但是这个方法可以满足我的用例。更正和改进是值得赞赏的。:-)

#3


1  

Using getEllipsisCount wont work with text that has empty lines within it. I used the following code to make it work :

使用get椭圆体将不会使用在其内部有空行的文本。我使用以下代码使其工作:

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.

确保不要在XML中设置maxLineCount。然后,您可以在代码中检查lineCount,如果它大于某个数字,您可以返回false来取消TextView的绘制,并设置行数和标志,以保存TextView是否太长。textview将使用正确的行计数再次绘制,您将知道它的大小是否为椭圆形。

You can then use the isEllipsized flag to do whatever you require.

然后,您可以使用is椭圆大小的标志来执行您需要的任何操作。