2011-12-26 2 views
17

Ho un lungo passaggio in un TextView che è avvolto da ScrollView. C'è un modo per trovare il testo visibile corrente?Ottieni testo visibile corrente in textview

Sono in grado di trovare il numero di linee, l'altezza della riga in vista testo e anche scorrere e scrolly da scrollview, ma trovare il collegamento al testo visualizzato corrente. Per favore aiuto! Grazie.

+0

è un'approssimazione va bene? – Snowball

+0

Ciao. Sto lavorando allo stesso problema. Avete qualche soluzione per questo. Devo scoprire la parte visibile del testo da TextView. Mi potete aiutare? –

+0

Per quanto ne so, non penso che ci sia un modo per farlo con TextView. – kosa

risposta

1

Si dichiara di conoscere scrollY, il numero corrente di pixel scorrevoli. Conosci anche l'altezza della finestra che stai considerando in pixel, quindi chiama questo scrollViewHeight. Quindi

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

È un'approssimazione, quindi usarlo come ultima risorsa.

+0

grazie per il tuo suggerimento, l'ho appena provato, l'approssimazione è buona per il passaggio breve. L'errore è troppo per il testo lungo che sto per visualizzare .... Sto pensando di ottenere TextPaint per misurare il testo e fare il calcolo se non troppo intensivo di calcolo. – John

14

E 'semplice per farlo:

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

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

Non funzionante, ottenendo l'eccezione del puntatore nullo – Jayesh

0

Prova Usa getEllipsisStart()

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

funziona solo per singleLine = "true" –

2

Qui. Ottieni il numero di linea della prima riga visualizzata. Quindi ottenere il numero di riga della seconda riga visualizzata. Quindi prendi il testo e conta il numero di parole.

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

Anche io ho lo stesso problema. Avevo bisogno della prima linea visibile da textview attualmente visibile in recyclerview. Se si sta tentando di ottenere attualmente visualizzata prima linea di TextView in recyclerview è possibile utilizzare il seguente codice:.

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

Utilizzando textView.getLayout() getEllipsisStart (0) funziona solo se Android: SingleLine = "true"

Ecco una soluzione che funziona se Android: maxLines è impostato:

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

Ricorda: questo funziona dopo la vista è già caricato.

Usage:

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