последнее слово, отображаемое в текстовом представлении

Я собираюсь отобразить полный текстовый документ на нескольких страницах в приложении для Android. Каждая страница содержит элемент управления TextView, отвечающий за отображение текста. Он также содержит кнопку «Далее», которая отвечает за обновление текстового представления и отслеживание текста с того места, где он закончился в последнем отображаемом разделе.
Проблема в том, как найти последнее отображаемое слово в отображаемой области TextView?
Примечание. В этом приложении textView не должен прокручиваться или использовать многоточие. Также следует отметить, что размер текста может быть увеличен или уменьшен. Чтобы лучше понять ситуацию: Образец текста, который будет отображаться:

Это весь текст. На первой странице он просто заканчивался здесь и должен следовать отсюда.

И это пример иллюстрации его дисплея. Вопрос в том, как найти слово «здесь» в качестве последнего слова, отображаемого на странице 1? А это пример иллюстрации его отображения. Вопрос в том, как найти слово здесь как последнее слово, отображаемое на странице 1  ?


person VSB    schedule 08.05.2012    source источник
comment
Текст будет всегда одинаковым или он может измениться?   -  person caiocpricci2    schedule 10.05.2012
comment
текст будет меняться динамически.   -  person VSB    schedule 11.05.2012


Ответы (2)


Я не могу попробовать эту идею сейчас, но давайте попробуем! В соответствии с этот пост вы можете использовать следующий метод, чтобы узнать, подходит ли строка в текстовом представлении.

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

Итак, одна идея, если текст всегда один и тот же, вы можете определить начальные значения для каждого текстового представления вручную, а затем, когда вы увеличиваете или уменьшаете шрифт, вы пересчитываете его, удаляя или добавляя слова.

Если нет возможности ввести начальные значения вручную, вы можете сделать что-то вроде:

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

Вам также нужно будет сохранить позицию первого слова textView, поэтому, когда вы изменяете размер текста, вы знаете, с чего начать!

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

И когда он изменяет размер, вы используете его тем же методом для вычисления текста на экране.

lastUsedWord = firstWordOnTextView;

Если вы хотите быть еще быстрее, вы можете отслеживать, сколько слов у вас есть на каждой странице, сделать среднее значение и после нескольких прогонов всегда статистику вашего цикла оттуда. Или несколько слов раньше, чтобы не повторяться.

Я считаю это разумным решением, если вам не нужно отображать слишком много страниц одновременно!

Извините за ошибки в коде, сейчас негде попробовать! Есть комментарии по поводу этого решения? Очень интересный вопрос!

person caiocpricci2    schedule 09.05.2012
comment
Спасибо за Ваш ответ. Ваш ответ тоже интересен и полезен. Однако он не подходит для многострочного TextView, так как вы должны учитывать интервалы по вертикали. И, наконец, в поисках оценки вертикального интервала я пришел к решениям, которые использовались в: This Post. Я опубликую свой код, когда закончу здесь. спасибо за ваше замечание :) - person VSB; 10.05.2012
comment
О, мой плохой, я этого не заметил! Ну да, поделитесь с нами :) - person caiocpricci2; 11.05.2012

Наконец, я разработал фрагмент кода, который может найти последнее отображаемое слово. Учитывая, что мы собираемся использовать текстовое представление со свойствами width и height в качестве размера и textSize в dp в качестве размера текста, функция formatStringToFitInTextView оценивает последнее отображаемое слово в текстовом представлении и возвращает его в качестве вывода функции. В приведенном ниже примере мы рассмотрели шрифт SERIF как гарнитуру 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;
}

Общая логика выполнения действий состоит в том, чтобы разбить входной текст на слова и добавить слова одно за другим в текстовое представление, пока оно не заполнит предоставленную высоту и ширину, а затем вернуть последнее добавленное слово как последнее отображаемое слово.

Примечание. Благодаря Moritz я использовал меру функции из этот ответ.

person VSB    schedule 12.05.2012