2011-12-26 55 views
17

我在包含ScrollView的TextView中有很長的一段。有什麼方法可以找到當前可見的文本嗎?在textview中獲取當前可見文本

我可以在textview中找到行數,行高以及滾動視圖中的scrollx和scrolly,但找到與當前顯示文本的鏈接。請幫忙!謝謝。

+0

是一種近似好嗎? – Snowball 2011-12-26 16:43:37

+0

嗨。我正在研究同樣的問題。你有什麼解決方案嗎?我需要從TextView中找出文本的可見部分。你可以幫我嗎? – 2012-07-17 06:45:07

+0

據我所知,我不認爲有一種方法可以用TextView來做到這一點。 – kosa 2011-12-26 15:42:29

回答

1

你聲稱你知道scrollY,當前滾動的像素數量。你也知道你正在考慮的像素的高度,所以請致電scrollViewHeight。然後

int scrollY; // This is your current scroll position in pixels. 
int scrollViewHeight; // This is the height of your scrolling window. 
TextView textView; // This is the TextView we're considering. 

String text = (String) textView.getText(); 
int charsPerLine = text.length()/textView.getLineCount(); 
int lineHeight = textView.getLineHeight(); 

int startLine = scrollY/lineHeight; 
int endLine = startLine + scrollViewHeight/lineHeight + 1; 

int startChar = charsPerLine * startLine; 
int endChar = charsPerLine * (endLine+1) + 1; 
String approxVisibleString = text.substring(startChar, endChar); 

這是一個近似值,所以用它作爲最後的手段。

+0

感謝您的建議,我剛剛嘗試過,這個近似適合短時間使用。這個錯誤對於我要顯示的長文本來說太多了....我正在考慮讓TextPaint來測量文本,並且如果計算密集程度不是太高,就要進行計算。 – John 2011-12-26 17:54:08

14

它是簡單的做到這一點:

int start = textView.getLayout().getLineStart(0); 
int end = textView.getLayout().getLineEnd(textView.getLineCount() - 1); 

String displayed = textView.getText().toString().substring(start, end); 
+1

沒有工作,獲得空指針異常 – Jayesh 2017-02-08 12:32:25

0

嘗試使用getEllipsisStart()

int end = textView.getLayout().getEllipsisStart(0); 
+0

這將只適用於singleLine =「true」 – 2017-11-25 10:29:46

2

這裏。獲取顯示的第一行的行號。然後獲取顯示的第二行的行號。然後獲取文本並計算單詞的數量。

private int getNumberOfWordsDisplayed() { 
     int start = textView.getLayout().getLineStart(getFirstLineIndex()); 
     int end = textView.getLayout().getLineEnd(getLastLineIndex()); 
     return textView.getText().toString().substring(start, end).split(" ").length; 
    } 

    /** 
    * Gets the first line that is visible on the screen. 
    * 
    * @return 
    */ 
    public int getFirstLineIndex() { 
     int scrollY = scrollView.getScrollY(); 
     Layout layout = textView.getLayout(); 
     if (layout != null) { 
      return layout.getLineForVertical(scrollY); 
     } 
     Log.d(TAG, "Layout is null: "); 
     return -1; 
    } 

    /** 
    * Gets the last visible line number on the screen. 
    * @return last line that is visible on the screen. 
    */ 
    public int getLastLineIndex() { 
     int height = scrollView.getHeight(); 
     int scrollY = scrollView.getScrollY(); 
     Layout layout = textView.getLayout(); 
     if (layout != null) { 
      return layout.getLineForVertical(scrollY + height); 
     } 
     return -1; 
    } 
1

我自己也有同樣的問題。我需要在回收站查看當前可見的textview中的第一行可見行。如果您想獲得當前顯示的TextView的第一行中recyclerview你可以使用下面的代碼:

TextView tv = (TextView) recyclerView.getChildAt(0); //gets current visible child view 
    // this is for top visible 
    //view or the textview directly 
    Rect r1 = new Rect(); 
    tv.getHitRect(r1);//gets visible rect of textview 
    Layout l = tv.getLayout(); 

    int line = l.getLineForVertical(-1 * r1.top);//first visible line 
    int start = l.getLineStart(line);//visible line start 
    int end = l.getLineEnd(line);//visible line end 

    String displayed = tv.getText().toString().substring(start, end); 
0

使用textView.getLayout()getEllipsisStart(0)只有工作,如果機器人:單線=「真」

下面是Android的,如果將工作的解決方案:MAXLINES設置:

public static String getVisibleText(TextView textView) { 
    // test that we have a textview and it has text 
    if (textView==null || TextUtils.isEmpty(textView.getText())) return null; 
    Layout l = textView.getLayout(); 
    if (l!=null) { 
     // find the last visible position 
     int end = l.getLineEnd(textView.getMaxLines()-1); 
     // get only the text after that position 
     return textView.getText().toString().substring(0,end); 
    } 

    return null; 
} 

記住:這個作品的觀點已經被加載後。

用法:

textView.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() { 
     @Override 
     public void onGlobalLayout() { 
      textView.getViewTreeObserver().removeOnGlobalLayoutListener(this); 
      Log.i("test" ,"VisibleText="+getVisibleText(textView)); 
     } 
    });