The Bat
The Bat

Reputation: 1105

Html Styling in textview goes wrong Android

I am selecting a part of the TextView and on click of a "highlight" button, I am sending the start and the end index of selection to the database. Then I am loading all the start and end indexes from db and changing the color of text between them.

The problem is after once or twice, the app is changing the color of text that is not in selection.. and the selected part remains unchanged.

MY CODE:

  1. When user selects and presses the highlight button

    int i=contentText.getSelectionStart();
    int j=contentText.getSelectionEnd();
    
    db.insertHiglightIndex(String.valueOf(i),String.valueOf(j));
    setHighlightedText();
    
  2. The setHighlightedText() method..

    String fullText=contentText.getText().toString();
    for(int i=0; i<db.getAllStartIndex().size();i++){
        String a=fullText.substring(Integer.parseInt(db.getAllStartIndex().get(i)),Integer.parseInt(db.getAllEndIndex().get(i)));
        fullText = fullText.replace(a, "<font color='red'>"+a+"</font>");
    }
    contentText.setText(Html.fromHtml(fullText), TextView.BufferType.SPANNABLE);
    

MY SCREENSHOTS.

The selection:

The Result:

Clearly the selected area is from "Garrick" to "Bart", and the result is from "entity" to "2012"

I am not able to understand why is this happening. I think there is some problem with this <font color='red'>"+a+"</font> line.

Thank you

Upvotes: 3

Views: 385

Answers (2)

Guillaume Barr&#233;
Guillaume Barr&#233;

Reputation: 4228

You have wrong indexes because you are modifying the fullText content within the loop.

Taking a look at this example you can figure it:

final TextView tv = (TextView) findViewById(R.id.textView);
tv.setText( "abcdefghijklmnopqrstuvwxyz0123456789");

String fullText= tv.getText().toString();

// your first iteration
String a = fullText.substring(1,3);
// a contains "ab"
fullText = fullText.replace(a, "<font color='red'>"+a+"</font>");

After the first iteration full text contains now

a<font color='red'>bc</font>defghijklmnopqrstuvwxyz0123456789"

Then the substring() in the second iteration won't returns the substring base on your initial content.

If you want to be able to have multiple substrings colored in red you can try this:

String fullText = contentText.getText().toString();
StringBuilder result = new StringBuilder();

for(int i=0; i < db.getAllStartIndex().size(); i++){
    fullText = applyFont(result, fullText, Integer.parseInt(db.getAllStartIndex().get(i)), Integer.parseInt(db.getAllEndIndex().get(i)));
}
// Add here the remaining content
result.append(fullText);
contentText.setText(Html.fromHtml(result.toString()), TextView.BufferType.SPANNABLE);


private String applyFont(StringBuilder result, String source, int from, int to){
    result.append(source.substring(0, from));
    result.append("<font color='red'>");
    result.append(source.substring(from, to));
    result.append("</font>");
    return source.substring(to, source.length());
}

Upvotes: 1

Shree Krishna
Shree Krishna

Reputation: 8562

It got wrong indexed because There is already added <font color='red'> in the beginning, So that in second time This tag is also counted as a part of string, So I suggest creating a new temporary String, assign same text to the String but after replacing the previous font tag it held. Use this syntax to remove previous font tag from originalString

String tempString = originalString.replaceAll("[<](/)?font[^>]*[>]", "");

After that work with only tempString. That means again add every previous font tag you have to tempString and set that text.

In next time again do the same first remove all font tag and again add all of them back in tempString as well as current selection using same loop you are using currently.

Upvotes: 2

Related Questions