Search code examples
javaandroidtextviewline-count

Separate second line of TextView into another TextView with Java


I'm trying to create a fill the gap game in Android Studio with Java, for that I'm taking a sentence, separating the keyword (to fill by the user) from the String, and adding the Strings as follow in a horizontal LinearLayout (within a vertical Layout):

TextView before keyword + TextView keyword + TextView after keyword

In a different LinearLayout below I have a following TextView (TextView Line3) making a second line with the same width as the horizontal LinearLayout above. -- Something like a line 2

As TextView after keyword is too long and makes a second line starting after the "TextView keyword", I want to take what goes to the second line of "TextView after keyword" and move it to "TextView Line3".

The problem is that it keeps saying there is only 1 line and "TextView after keyword" displays two

I defined them as such:

private TextView firstSentence, secondSentence, thirdSentence;
public TextView answerText;

private String sentence = "I do not like anyone in this world of idiots";

private boolean newLineBoolean = true;
private String keyword = "like";
private String[] sentenceDivision;

private String displayForKeyword = "";
private String thirdLine = "";

this in onCreate

answerText = findViewById(R.id.answerPlace);

firstSentence = findViewById(R.id.firstSentence);
secondSentence = findViewById(R.id.secondSentence);
thirdSentence = findViewById(R.id.thirdSentence);


sentenceDivision = sentence.split(keyword);
firstSentence.setText(sentenceDivision[0]);
secondSentence.setText(sentenceDivision[1]);


for(int i = 0; i<keyword.length();i++)
{
    displayForKeyword = displayForKeyword + "   ";
}
answerText.setText(displayForKeyword);
checkNumberOfLines();

And this method

private void checkNumberOfLines(){

    String firstWords = sentenceDivision[1].substring(0, sentenceDivision[1].lastIndexOf(" "));
    String lastWord = sentenceDivision[1].substring(sentenceDivision[1].lastIndexOf(" ") + 1);
    sentenceDivision[1] = firstWords;
    thirdLine = lastWord + " " + thirdLine;
    secondSentence.setText(sentenceDivision[1]);
    thirdSentence.setText(thirdLine);

    secondSentence.post(new Runnable() {
        @Override
        public void run() {
            int lineCount = secondSentence.getLineCount();
            if (lineCount > 0) {
                checkNumberOfLines();
            }
            else{ newLineBoolean = false;
            }
        }
    });

}

But it displays as follows:

enter image description here

Does someone know why? Thanks in advance!


Solution

  • It might be because of the definition of TextView.getLineCount()

    public int getLineCount() {
        return mLayout != null ? mLayout.getLineCount() : 0;
    }
    

    if mLayout is a BoringLayout then getLineCount() always returns 1. To use a different kind of text layout (DynamicLayout) that actually computes its line count, you could try either to make the text selectable by calling setTextIsSelectable or set a Spannable instead of a CharSequence in the TextView (see makeSingleLayout).

    I agree with your sentence and this is not the best solution for your use case for which you might get less trouble by using something like a FlowLayout instead of the LinearLayouts and placing each word inside a separate TextView.


    Edit to answer questions in comment

    1. After adding the FlowLayout to the activity's layout xml you can create the TextViews for the words in the sentence dynamically:
        // in onCreate()
        FlowLayout flowLayout = findViewById(R.id.flow_id);
    
        String[] words = sentence.split(" ");
        TextView wordText;
        for (int i = 0; i < words.length; i++) {
            String word = words[i];
            //if an edit text is needed for user input
            if (i == keywordIndex) {
               wordText = new EditText(this);
               wordText.setHint("____"); 
            } else {
               wordText = new TextView(this);           
               wordText.setText(word);
            }
            wordText.setTextColor(getResources()
                                       .getColor(R.color.your_color));
            wordText.setBackgroundColor(getResources()
                                       .getColor(android.R.color.white));
            flowLayout.add(wordText);
        }
    
    
    1. Yes, you could use a RecyclerView with a GridLayoutManager or StaggeredGridLayoutManager to layout the views for the sentence words but it would require creating a RecyclerView.Adapter. But I think the RecyclerView would be more suitable for displaying a vertical set of sentences (as FlowLayouts for example).