2012-05-08 19 views
8

Ho intenzione di visualizzare un documento di testo completo su diverse pagine in un'app per Android. Ogni pagina contiene un controllo TextView che è responsabile della visualizzazione del testo. Contiene anche un pulsante successivo, che ha il compito di aggiornare la visualizzazione del testo e seguire il testo proprio da dove è terminato nell'ultima sezione visualizzata.
Il problema è come posso trovare l'ultima parola visualizzata nell'area visualizzabile di TextView?
Nota: In questa app, textView non è che si suppone debba scorrere o utilizzare ellipize. Si deve inoltre notare che textize può essere aumentato o diminuito. Per comprendere meglio la situazione: Testo di esempio da visualizzare:ultima parola visualizzata in una vista testuale

Questo è tutto il testo. Alla prima pagina è appena terminato lo qui e deve essere seguito da qui.

E questa è l'illustrazione di esempio del suo display. La domanda è come trovare la parola "qui" come ultima parola visualizzata nella pagina 1? And this is the sample illustration of the its display. The question is how to find word "here" as last word displayed in page 1?

+0

Il testo sarà sempre lo stesso o può cambiare? – caiocpricci2

+0

il testo verrà modificato dinamicamente. – VSB

risposta

1

Infine ho sviluppato un pezzo di codice che può trovare l'ultima parola visualizzata. Considerando che stiamo per utilizzare una visualizzazione testo con proprietà larghezza e altezza come le sue dimensioni e textSize in dp come dimensioni del testo, funzione formatStringToFitInTextView valuta l'ultima parola visualizzata nella TextView e lo restituisce come funzione produzione. Nell'esempio sottostante abbiamo considerato il font SERIF come carattere tipografico TextView.

String formatStringToFitInTextView(int width, int heigth, String inputText,float textSize) { 
    String[] words; 
    String lastWord = ""; 
    String finalString=""; 
    StaticLayout stLayout; 
    int i,numberOfWords; 
    int h; 
    Typeface tf = Typeface.SERIF; 
    TextPaint tp = new TextPaint(); 
    tp.setTypeface(tf); 
    tp.setTextSize(textSize); //COMPLEX_UNIT_DP 

    words = inputText.split(" "); //split input text to words 
    numberOfWords = words.length; 
    for (i=0;i<numberOfWords;i++){ 
     stLayout= measure(tp,finalString+words[i]+" ",width); 
     h=stLayout.getHeight(); 
     if (stLayout.getHeight() > heigth) break; 
     finalString += words[i]+" "; 
     lastWord = words[i]; 
    } 

    return lastWord; 
} 
StaticLayout measure(TextPaint textPaint, String text, Integer wrapWidth) { 
    int boundedWidth = Integer.MAX_VALUE; 
    if(wrapWidth != null && wrapWidth > 0) { 
     boundedWidth = wrapWidth; 
    } 
    StaticLayout layout = new StaticLayout(text, textPaint, boundedWidth, Alignment.ALIGN_NORMAL, 1.0f, 0.0f, false); 
    return layout; 
} 

La logica totale a fare azioni è diviso il testo di input in parole e aggiungere le parole una ad una per TextView fino a che riempie l'altezza e la larghezza prevista e poi tornare l'ultima parola aggiunta come ultima parola visualizzata.

Nota: grazie a Moritz, ho utilizzato la funzione di misura da this answer.

1

Non posso provare ora questa idea, ma facciamolo! In base a this post è possibile utilizzare il seguente metodo per scoprire se una stringa si adatta a una vista testo.

private boolean isTooLarge (TextView text, String newText) { 
    float textWidth = text.getPaint().measureText(newText); 
    return (textWidth >= text.getMeasuredWidth()); 
} 

Quindi una sola idea, se il testo è sempre lo stesso, è possibile definire i valori iniziali per ogni vista del testo manualmente e poi quando si aumenta o diminuisce il tipo di carattere si ricalcola esso, la rimozione o l'aggiunta di parole.

Se non è un'opzione per inserire i valori iniziali manualmente si può fare qualcosa di simile:

String wordsInTextview = new String(); 
int lastUsedWord= 0; 
int totalNumberOfWords = text.size(); 
    for (int i=lastUsedWord;i<totalNumberOfWords;i++) {    
     if !(isTooLarge(TextView,wordsInTextview)) { 
      wordsInTextview = wordsInTextview + text(i); // add the words to be shown 
     } else { 
     TextView.setText(wordsInTextView); 
     lastUsedWord= i; 
     wordsInTextView = new String(); // no idea if this will erase the textView but shouldn't be hard to fix  
     }  
    } 

Si sarebbe anche bisogno di memorizzare la posizione della prima parola del textView, in modo che quando si ridimensiona il testo sai da dove iniziare!

int firstWordOnTextView = TextView.getText().toString().split(" ")[0] 

E quando si ridimensiona lo si utilizza lo stesso metodo per calcolare il testo sullo schermo.

lastUsedWord = firstWordOnTextView; 

Se si vuole essere ancora più veloce, è possibile mantenere una traccia di quante parole si dispone in ogni pagina, fare una media e, dopo un paio di basi stat sempre il ciclo da lì. O qualche parola prima per evitare di dover ripetere iterate.

Credo che questa sia una soluzione ragionevole se non è necessario visualizzare troppe pagine contemporaneamente!

Siamo spiacenti per gli errori nel codice Non ho dove provarlo ora! Qualche commento su questa soluzione? Domanda molto interessante!

+0

Grazie per la risposta. La tua risposta è anche interessante e utile. Tuttavia non è adatto a TextView multiriga poiché è necessario tenere conto della spaziatura verticale. E alla ricerca della stima della spaziatura verticale, infine, arrivo alle soluzioni utilizzate in: [Questo post] (http://stackoverflow.com/questions/7549182/android-paint-measuretext-vs-gettextbounds). Pubblicherò il mio codice una volta finito qui. grazie per la tua nota :) – VSB

+0

Oh, mio ​​male, non me ne sono accorto! Beh, sì, condividilo con noi :) – caiocpricci2

+0

puoi avere una risposta ora :) – VSB

Problemi correlati