Home » Android » java – Remove span when text inside the span is changed in Android

java – Remove span when text inside the span is changed in Android

Posted by: admin May 14, 2020 Leave a comment

Questions:

Let´s say I make a comment like this:
Hi Andrea check this out….. In that comment I want to highlight Andrea, but whenever I change the value of Andrea or when I delete one character of the word the span changes, the problem is that I´m using spannableString.setSpan(new StyleSpan(Typeface.BOLD), indexOfAt, highlightName.length() + indexOfAt, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE), which Spanned.SPAN_EXCLUSIVE_EXCLUSIVE accepts words in the middle and deletion of words, how can I remove the span when the user changes the word or delete a character of the word?

How to&Answers:

You need to watch for Text change on the edit text.
Assuming the EditText, you are using is named as commentEditText

 commentEditText.addTextChangedListener(new TextWatcher() {
            @Override
            public void beforeTextChanged(CharSequence charSequence, int i, int i1, int i2) {

            }

            @Override
            public void onTextChanged(CharSequence charSequence, int i, int i1, int i2) {

            }

            @Override
            public void afterTextChanged(Editable editable) {
                String comment = editable.toString();
                if (comment.indexOf('@') != -1) {
                    //Asumming the name string
                    String name = "Andrea";
                    int atIndex = comment.indexOf('@');
                    int endIndex = atIndex + name.length() + 1;
                    if (endIndex == -1 || endIndex > editable.length()) {
                        endIndex = editable.length();
                    }
                    if (comment.toLowerCase().contains(name.toLowerCase())) {
                        editable.setSpan(new StyleSpan(Typeface.BOLD), atIndex, endIndex, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
                    } else {
                        StyleSpan[] spannable = editable.getSpans(atIndex, endIndex, StyleSpan.class);
                        if (spannable != null && spannable.length > 0) {
                            for (int i = 0; i < spannable.length; i++) {
                                editable.removeSpan(spannable[i]);
                            }
                        }

                    }
                }
            }
        });

Answer:

If you are using the SpannableString you have to recreate the whole thing on every change.

You can remove spans but you cannot change the source (the comment) because SpannableString source text is immutable.

I suggest on every change of the comment you create the SpannableString, look for names and tag them, then if the comment changes you repeat the same thing with a new SpannableString. There will be no performance problems because the comments are small in size.

If you want to have a mutable object you can use the SpannableStringBuilder but it’s more complicated and there is no need for it.

Answer:

You can try TextWatcher for this, simply add TextWatcher to the textview you want to achieve above and in on

 @Override
    public void onTextChanged(CharSequence s, int start, int before, int count) {
//Do some magic here
    }

Now whenever user types or deletes any character you will get a callback in this method upon receiving that you can reset your span.