2011-12-26 76 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)); 
     } 
    });