Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

last word displayed in a textview

I'm going to display a complete text document on several pages in an android app. Each page contains a TextView control which is in charge to display text. It also contains a next button, which is in charge to update textview and follow the text just from where it ended in last displayed section.
The problem is how can i find the last displayed word in displayable area of TextView?
Note: In this app, textView is not supposed to be scrolled or use ellipsize. It also must be noted textsize can be increased or decreased. To understand the situation better: Sample Text to be displayed:

This is whole text. At first Page It just ended here and must be followed from here.

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

like image 498
VSB Avatar asked May 08 '12 13:05

VSB


People also ask

How do you get 3 dots at the end of a TextView text?

You are applying to your TextView a compound Drawable on the right.. to make the three dots appear in this scenario, you have to apply a android:drawablePadding="{something}dp" attribute to the TextView as well. Hope it helps!

What is a TextView?

A TextView displays text to the user and optionally allows them to edit it. A TextView is a complete text editor, however the basic class is configured to not allow editing.

What is the difference between an EditText and a TextView?

EditText is used for user input. TextView is used to display text and is not editable by the user. TextView can be updated programatically at any time.


2 Answers

I can't try this idea now but let's give it a shot! According to this post you can use the following method to find out if a string fits in a textview.

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

So one idea, if the text is always the same, you can define the initial values for each text view manually and then when you increase or decrease the font you recalculate it, removing or adding words.

If it's not an option to input the initial values manually you can do something like:

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

You also would need to store the position of the first word of the textView, so when you resize the text you know where to start from!

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

And when it resizes you use it in the same method to calculate the text on the screen.

lastUsedWord = firstWordOnTextView;

If you want to be even faster, you can keep a track of how many words you have on each page, make an average and after a few runs always stat your loop from there. Or a few words before to avoid having to iterate back.

I believe this a reasonable solution if you don't have to display too many pages at once!

Sorry for mistakes in the code I don't have where to try it now! Any comments about this solution? Very interesting question!

like image 109
caiocpricci2 Avatar answered Oct 12 '22 23:10

caiocpricci2


Finally I developed piece of code which can find last displayed word. Considering that we are going to use a text view with properties width and height as its size and textSize in dp as size of text, function formatStringToFitInTextView evaluates the last displayed word in the textview and returns it to as function output. In below sample we considered SERIF font as TextView typeface.

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

The total logic to do actions is split the input text into words and add words one by one to textview till it fills up the provided height and width and then return the last added word as last displayed word.

Note: Thanks to Moritz, I used function measure from this answer.

like image 42
VSB Avatar answered Oct 12 '22 23:10

VSB