chiranjib
chiranjib

Reputation: 5308

Change Text style format in EditText at runtime

I have the following requirement:

i> User enters a string in an EditText.

e.g: aaaaaaa bbbbbbbbb ccccccccccccc

ii> User now selects the substring "bbbbbbbbb" and adds a bold style to the substring.

Selection of the substring is done with the following code:

EditText content = (EditText) layout
            .findViewById(R.id.txt_content);
int startSelection = content.getSelectionStart();
int endSelection = content.getSelectionEnd();

Now , applying the bold style to the substring , the following code has been added to reflect the style on the EditText:

final SpannableStringBuilder str1 = new SpannableStringBuilder(content.getText().toString());
str1.setSpan(new android.text.style.StyleSpan(android.graphics.Typeface.BOLD), startSelection, endSelection, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);               
content.setText(str1);

iii> Now the user modifies the original string. Lets assume the new string to be

e.g: aaaaaaa bbbbbbbbb ccccccccccccc ddddddddd

Now user wants to apply underline style on the substring "ddddddddd" Now , before underline , the current text is fetched from the EditText using the following code: content.getText()

The issue is the text fetched using content.getText() doesnot contain the BOLD style which has been applied on the substring "bbbbbbbbb".

Basically the requirement is to apply different styles(bold/italic) on individual characters/words in a sentence by selection. Modification(addition / removal of characters/words) of the sentence is also possible.

How to resolve the issue ?

Upvotes: 1

Views: 1151

Answers (2)

Naveen Dissanayake
Naveen Dissanayake

Reputation: 672

You know if you are not appending text you don't have to use SpannableStringBuilder you can use a Spannable text. Anyways I think your problem is your converting your text to String.

Spannable spannable = new SpannableString(mEditText.getText());
spannable.setSpan(new StyleSpan(Typeface.BOLD),
                    mEditText.getSelectionStart(),
                    mEditText.getSelectionEnd(),
                    Spannable.SPAN_INCLUSIVE_INCLUSIVE);

mEditText.setText(spannable);

But if your code is going to overlap styles you will have to handle it in a different way.

Upvotes: 1

Emanuel
Emanuel

Reputation: 8106

 EditText content = (EditText) layout.findViewById(R.id.txt_content);
 int startSelection = content.getSelectionStart();
 int endSelection = content.getSelectionEnd();

 // important. dont use getText() 
 Spannable sb = new SpannableString( content.toString() );

 /** for bold for example. substract the endselection from startselection to get the length **/
 sb.setSpan(new StyleSpan(android.graphics.Typeface.BOLD), startSelection, endSelection - startSelection, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE); //bold
 /** do more styles ...**/
 sb.setSpan(new UnderlineSpan(), 20, 30, 0); 

 content.setText(sb);

to show this in TextView

textview.setText(sb);

You can also grab all Assigned Styles with:

StyleSpan[] mSpans = content.getText().getSpans(0, content.length(), StyleSpan.class);

and read the different styles by checking the class.

for (StyleSpan mSpan : mSpans) {
    if (mSpan instanceof StyleSpan) { 
    int start = content.getSpanStart(mSpan);
    int end = content.getSpanEnd(mSpan);
    int flag = content.getSpanFlags(mSpan);
    Log.i("SpannableString Spans", "Found StyleSpan at:\n" +
            "Start: " + start + 
             "\n End: " + end + 
             "\n Flag(s): " + flag);
    }
}    

Upvotes: 3

Related Questions