簡體   English   中英

如何判斷我的 textview 是否已被省略?

[英]How do I tell if my textview has been ellipsized?

我有一個多行TextView ,其中設置了android:ellipsize="end" 但是,我想知道我放在那里的字符串是否真的太長(這樣我可以確保完整的字符串顯示在頁面的其他地方)。

我可以使用TextView.length()並找出適合的字符串的大致長度,但由於它是多行, TextView處理何時換行,因此這並不總是有效。

有任何想法嗎?

您可以獲取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");
}

這僅在布局階段之后有效,否則返回的布局將為空,因此在代碼中的適當位置調用它。

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

我認為這個問題最簡單的解決方案是以下代碼:

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

此代碼假定在您的 XML 中 TextView 設置了maxLineCount :)

這對我有用:

textView.post(new Runnable() {
                        @Override
                        public void run() {
                            if (textView.getLineCount() > 1) {
                                //do something
                            }
                        }
                    });

public 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

我找到的最有說服力的解決方案(在 Kotlin 中)是在TextView上創建一個擴展函數

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

這很棒,因為它不需要知道完整的字符串是什么或擔心TextView使用了多少行。

TextView.text是它試圖顯示的全文,而TextView.layout.text是實際顯示在屏幕上的內容,所以如果它們不同,它必須被橢圓化

要使用它:

if (my_text_view.isEllipsized()) {
    ...
}
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”

Kotlin 方式:

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

實際上View.post()是在視圖渲染后執行的,並且會運行提供的函數

簡單的 Kotlin 方法。 允許使用android:ellipsizeandroid:maxLines

fun isEllipsized(textView: TextView, text: String?) = textView.layout.text.toString() != text

它對我有用

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

確實如此,例如,將完整數據從 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());
                                    }
                                }
                            });
                        }
                    }
                }
            });

將 @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
}

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

這是用於創建可擴展文本視圖的簡單庫。 喜歡繼續或更少。 這個庫擴展版本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);

如果您的 textview 包含多個段落,則使用 getEllipsisCount 將不適用於其中的空行。 任何段落最后一行的 getEllipsisCount 將返回 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

經過研究,我在 Kotlin 找到了最適合我的方法

textView 必須先渲染才能得到橢圓狀態,所以我們要先設置文本,然后檢查 textView 里面的橢圓邏輯。post scope

textView.text = "your text"
textView.post {
    var ellipsized: Boolean = textView.layout.text.toString()).equalsIgnoreCase("your text"))

    if(ellipsized){
        //your logic goes below
      
    }
}

使用getEllipsisCount不適用於其中包含空行的文本。 我使用以下代碼使其工作:

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

確保不要在您的 XML 中設置maxLineCount 然后你可以在你的代碼中檢查lineCount ,如果它大於某個數字,你可以返回false取消TextView的繪制並設置行數以及一個標志來保存文本視圖是否太長與否。 文本視圖將使用正確的行數再次繪制,您將知道它是否帶有標志為橢圓形。

然后,您可以使用isEllipsized標志來執行您需要的任何操作。

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()不能在 view(layout) 設置之前調用。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM