82

TextView我有一个已设置的多行android:ellipsize="end"。但是,我想知道,如果我放在那里的字符串实际上太长(以便我可以确保完整的字符串显示在页面的其他地方)。

我可以使用TextView.length()并找到适合的字符串的大致长度,但由于它是多行的,TextView所以何时换行的句柄,所以这并不总是有效。

有任何想法吗?

4

18 回答 18

131

您可以获取布局TextView并检查每行的省略号数。对于结束省略号,检查最后一行就足够了,如下所示:

Layout l = textview.getLayout();
if (l != null) {
    int lines = l.getLineCount();
    if (lines > 0)
        if (l.getEllipsisCount(lines-1) > 0)
            Log.d(TAG, "Text is ellipsized");
}

这仅在布局阶段之后有效,否则返回的布局将为空,因此请在代码中的适当位置调用它。

于 2010-10-24T14:54:27.953 回答
37

textView.getLayout 是要走的路,但问题是如果没有准备好布局,它会返回 null 。使用以下解决方案。

 ViewTreeObserver vto = textview.getViewTreeObserver();
    vto.addOnGlobalLayoutListener(new OnGlobalLayoutListener() {
        @Override
        public void onGlobalLayout() {
           Layout l = textview.getLayout();
           if ( l != null){
              int lines = l.getLineCount();
              if ( lines > 0)
                  if ( l.getEllipsisCount(lines-1) > 0)
                    Log.d(TAG, "Text is ellipsized");
           }  
        }
    });

删除监听器的代码片段(source):

mLayout.getViewTreeObserver().addOnGlobalLayoutListener(new OnGlobalLayoutListener() {
    public void onGlobalLayout() {
        scrollToGridPos(getCenterPoint(), false);
        mLayout.getViewTreeObserver().removeOnGlobalLayoutListener(this);        
    }
});
于 2013-10-08T07:20:32.167 回答
36

我认为这个问题最简单的解决方案是以下代码:

String text = "some looooong text";
textView.setText(text);
boolean isEllipsize = !((textView.getLayout().getText().toString()).equalsIgnoreCase(text));

此代码假定在您的 XML 中 TextView 设置了一个maxLineCount:)

于 2015-11-06T11:47:44.960 回答
9

这对我有用:

textView.post(new Runnable() {
                        @Override
                        public void run() {
                            if (textView.getLineCount() > 1) {
                                //do something
                            }
                        }
                    });
于 2018-07-27T17:05:22.483 回答
6

我发现(在 Kotlin 中)最有说服力的解决方案是在TextView

fun TextView.isEllipsized() = layout.text.toString() != text.toString()

这很棒,因为它不需要知道完整的字符串是什么,也不需要担心TextView它使用了多少行。

TextView.text是它试图显示的全文,而TextView.layout.text实际上是屏幕上显示的内容,所以如果它们不同,它必须被省略

要使用它:

if (my_text_view.isEllipsized()) {
    ...
}
于 2021-01-07T22:14:32.003 回答
5

公共 int getEllipsisCount (int line)

返回要省略的字符数,如果没有省略,则返回 0。

所以,只需调用:

int lineCount = textview1.getLineCount();

if(textview1.getLayout().getEllipsisCount(lineCount) > 0) {
   // Do anything here..
}

由于在设置布局之前无法调用 getLayout(),因此使用以下命令:

ViewTreeObserver vto = textview.getViewTreeObserver();
vto.addOnGlobalLayoutListener(new OnGlobalLayoutListener() {
    @Override
    public void onGlobalLayout() {
       Layout l = textview.getLayout();
       if ( l != null){
          int lines = l.getLineCount();
          if ( lines > 0)
              if ( l.getEllipsisCount(lines-1) > 0)
                Log.d(TAG, "Text is ellipsized");
       }  
    }
});

最后,当您不再需要它时,不要忘记删除removeOnGlobalLayoutListener 。

于 2014-02-21T07:32:05.410 回答
3
lateinit var toggleMoreButton: Runnable
toggleMoreButton = Runnable {
  if(reviewTextView.layout == null) { // wait while layout become available
       reviewTextView.post(toggleMoreButton) 
       return@Runnable
  }
  readMoreButton.visibility = if(reviewTextView.layout.text.toString() != comment) View.VISIBLE else View.GONE
}
reviewTextView.post(toggleMoreButton)

这是一些典型的案例:

  1. 在“reviewTextView”中发表评论
  2. 评论可以按某些标准折叠
  3. 如果评论折叠,您将显示按钮“readMoreButton”
于 2018-12-22T05:32:32.247 回答
3

Kotlin 方式:

textView.post {
   if (textView.lineCount > MAX_LINES_COLLAPSED) {
   // text is not fully displayed
   }
}

实际上View.post()是在视图渲染后执行并运行提供的函数

于 2019-09-24T11:36:00.503 回答
2

简单的 Kotlin 方法。允许android:ellipsizeandroid:maxLines被使用

fun isEllipsized(textView: TextView, text: String?) = textView.layout.text.toString() != text
于 2020-09-01T18:02:32.720 回答
1

它对我有用

if (l != null) {
    int lines = l.getLineCount();
     if (lines > 0) {
     for (int i = 0; i < lines; i++) {
     if (l.getEllipsisCount(i) > 0) {
      ellipsize = true;
      break;
     }
    }
   }
  }
于 2016-08-29T03:58:53.547 回答
0

确实如此,例如,将完整数据从 RecyclerView 项传递给对话框:

holder.subInfo.post(new Runnable() {
                @Override
                public void run() {
                    Layout l = holder.subInfo.getLayout();
                    if (l != null) {
                        final int count = l.getLineCount();
                        if (count >= 3) {
                            holder.subInfo.setOnClickListener(new View.OnClickListener() {
                                @Override
                                public void onClick(View view) {
                                    final int c = holder.subInfo.getLineCount();
                                    if (c >= 3) {
                                        onClickToShowInfoDialog.showDialog(holder.title.getText().toString(), holder.subInfo.getText().toString());
                                    }
                                }
                            });
                        }
                    }
                }
            });
于 2018-05-13T16:38:06.547 回答
0

将@Thorstenvv awnser 与@Tiano 修复相结合,这里是 Kotlin 版本:

val layout = textView.layout ?: return@doOnLayout
val lines = layout.lineCount
val hasLine = lines > 0
val hasEllipsis = ((lines - 1) downTo 0).any { layout.getEllipsisCount(it) > 0 }
if (hasLine && hasEllipsis) {
    // Text is ellipsized
}
于 2019-10-29T14:50:59.217 回答
0

Kotlin中,您可以使用以下代码。

var str= "Kotlin is one of the best languages."
textView.text=str
textView.post {
val isEllipsize: Boolean = !textView.layout.text.toString().equals(str)

if (isEllipsize) {
     holder.itemView.tv_viewMore.visibility = View.VISIBLE
} else {
     holder.itemView.tv_viewMore.visibility = View.GONE
}    
}
于 2020-06-20T12:44:03.957 回答
0

这是用于创建可扩展的 textview 的简单库。喜欢继续或更少。该库扩展版 TextView。便于使用。

implementation 'com.github.mahimrocky:ShowMoreText:1.0.2'

像这样,1 https://raw.githubusercontent.com/mahimrocky/ShowMoreText/master/screenshot1.png

2 https://raw.githubusercontent.com/mahimrocky/ShowMoreText/master/screenshot2.png

 <com.skyhope.showmoretextview.ShowMoreTextView
    android:id="@+id/text_view_show_more"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:text="@string/text"
    />

在活动中,您可以使用如下:

ShowMoreTextView textView = findViewById(R.id.text_view_show_more);

//You have to use following one of method    

// For using character length
textView.setShowingChar(numberOfCharacter);
//number of line you want to short
textView.setShowingLine(numberOfLine);
于 2021-02-04T01:31:13.467 回答
0

如果您的 textview 包含多个段落,则使用 getEllipsisCount 将不适用于其中的空行。任何段落最后一行的 getEllipsisCount 将返回 0。

于 2021-04-19T20:41:57.163 回答
0

使用 kotlin 扩展的解决方案:

infoText.afterLayoutConfiguration {
    val hasEllipsize = infoText.hasEllipsize()
    ...
}

扩展:

/**
 * Function for detect when layout completely configure.
 */
fun View.afterLayoutConfiguration(func: () -> Unit) {
    viewTreeObserver?.addOnGlobalLayoutListener(object : ViewTreeObserver.OnGlobalLayoutListener {
        override fun onGlobalLayout() {
            viewTreeObserver?.removeOnGlobalLayoutListener(this)
            func()
        }
    })
}

fun TextView.hasEllipsize(): Boolean = layout.getEllipsisCount(lineCount - 1) > 0
于 2021-05-20T10:26:34.927 回答
-1

UsinggetEllipsisCount不适用于其中包含空行的文本。我使用以下代码使其工作:

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;
        }
    });

确保不要maxLineCount在您的 XML 中设置 a。然后你可以检查lineCount你的代码中的 ,如果它大于某个数字,你可以返回 false 以取消绘制TextView并设置行数以及一个标志来保存文本视图是否太长. 文本视图将使用正确的行数再次绘制,您将知道它是否带有标志的椭圆形。

然后,您可以使用该isEllipsized标志来执行您需要的任何操作。

于 2015-02-14T17:18:05.663 回答
-1

在TextViewUtils类中创建一个方法

public static boolean isEllipsized(String newValue, String oldValue) {
    return !((newValue).equals(oldValue));
}

在需要时调用此方法,例如:

        if (TextViewUtils.isEllipsized(textviewDescription.getLayout().getText().toString(), yourModelObject.getDescription()))
            holder.viewMore.setVisibility(View.VISIBLE);//show view more option
        else
            holder.viewMore.setVisibility(View.GONE);//hide 

但是textView.getLayout()不能在视图(布局)设置之前调用。

于 2017-03-28T09:15:02.297 回答