RTEditor/src/main/java/com/onegravity/rteditor/effects/CharacterEffect.java
public void applyToSelection(RTEditText editor, V value) {
        Selection selection = getSelection(editor);
        // SPAN_INCLUSIVE_INCLUSIVE is default for empty spans
        int flags = selection.isEmpty() ? Spanned.SPAN_INCLUSIVE_INCLUSIVE : Spanned.SPAN_EXCLUSIVE_INCLUSIVE;

        Spannable str = editor.getText();

        for (RTSpan<V> span : getSpans(str, selection, SpanCollectMode.SPAN_FLAGS)) {
            boolean sameSpan = span.getValue().equals(value);
            int spanStart = str.getSpanStart(span);
            if (spanStart < selection.start()) {
                // process preceding spans
                if (sameSpan) {
                    // we have a preceding span --> use SPAN_EXCLUSIVE_INCLUSIVE instead of SPAN_INCLUSIVE_INCLUSIVE
                    flags = Spanned.SPAN_EXCLUSIVE_INCLUSIVE;
                    selection.offset(selection.start() - spanStart, 0);
                } else {
                    str.setSpan(newSpan(span.getValue()), spanStart, selection.start(), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
                }
            }
            int spanEnd = str.getSpanEnd(span);
            if (spanEnd > selection.end()) {
                // process succeeding spans
                if (sameSpan) {
                    selection.offset(0, spanEnd - selection.end());
                } else {
                    str.setSpan(newSpan(span.getValue()), selection.end(), spanEnd, Spanned.SPAN_EXCLUSIVE_INCLUSIVE);
                }
            }
            str.removeSpan(span);
        }

        if (value != null) {
            RTSpan<V> newSpan = newSpan(value);
            if (newSpan != null) {
                str.setSpan(newSpan, selection.start(), selection.end(), flags);
            }
        }
    }
public void applyToSelection(RTEditText editor, V value) {
        Selection selection = getSelection(editor);
        // SPAN_INCLUSIVE_INCLUSIVE is default for empty spans
        int flags = selection.isEmpty() ? Spanned.SPAN_INCLUSIVE_INCLUSIVE : Spanned.SPAN_EXCLUSIVE_INCLUSIVE;

        Spannable str = editor.getText();

        for (RTSpan<V> span : getSpans(str, selection, SpanCollectMode.SPAN_FLAGS)) {
            boolean sameSpan = span.getValue().equals(value);
            int spanStart = str.getSpanStart(span);
            if (spanStart < selection.start()) {
                // process preceding spans
                if (sameSpan) {
                    // we have a preceding span --> use SPAN_EXCLUSIVE_INCLUSIVE instead of SPAN_INCLUSIVE_INCLUSIVE
                    flags = Spanned.SPAN_EXCLUSIVE_INCLUSIVE;
                    selection.offset(selection.start() - spanStart, 0);
                } else {
                    str.setSpan(newSpan(span.getValue()), spanStart, selection.start(), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
                }
            }
            int spanEnd = str.getSpanEnd(span);
            if (spanEnd > selection.end()) {
                // process succeeding spans
                if (sameSpan) {
                    selection.offset(0, spanEnd - selection.end());
                } else {
                    str.setSpan(newSpan(span.getValue()), selection.end(), spanEnd, Spanned.SPAN_EXCLUSIVE_INCLUSIVE);
                }
            }
            str.removeSpan(span);
        }

        if (value != null) {
            RTSpan<V> newSpan = newSpan(value);
            if (newSpan != null) {
                str.setSpan(newSpan, selection.start(), selection.end(), flags);
            }
        }
    }
public void applyToSelection ( RTEditText editor , V value ) { Selection selection = getSelection ( editor ) ; // SPAN_INCLUSIVE_INCLUSIVE is default for empty spans int flags = selection . isEmpty ( ) ? Spanned . SPAN_INCLUSIVE_INCLUSIVE : Spanned . SPAN_EXCLUSIVE_INCLUSIVE ; Spannable str = editor . getText ( ) ; for ( RTSpan < V > span : getSpans ( str , selection , SpanCollectMode . SPAN_FLAGS ) ) { boolean sameSpan = span . getValue ( ) . equals ( value ) ; int spanStart = str . getSpanStart ( span ) ; if ( spanStart < selection . start ( ) ) { // process preceding spans if ( sameSpan ) { // we have a preceding span --> use SPAN_EXCLUSIVE_INCLUSIVE instead of SPAN_INCLUSIVE_INCLUSIVE flags = Spanned . SPAN_EXCLUSIVE_INCLUSIVE ; selection . offset ( selection . start ( ) - spanStart , 0 ) ; } else { str . setSpan ( newSpan ( span . getValue ( ) ) , spanStart , selection . start ( ) , Spanned . SPAN_EXCLUSIVE_EXCLUSIVE ) ; } } int spanEnd = str . getSpanEnd ( span ) ; if ( spanEnd > selection . end ( ) ) { // process succeeding spans if ( sameSpan ) { selection . offset ( 0 , spanEnd - selection . end ( ) ) ; } else { str . setSpan ( newSpan ( span . getValue ( ) ) , selection . end ( ) , spanEnd , Spanned . SPAN_EXCLUSIVE_INCLUSIVE ) ; } } str . removeSpan ( span ) ; } if ( value != null ) { RTSpan < V > newSpan = newSpan ( value ) ; if ( newSpan != null ) { str . setSpan ( newSpan , selection . start ( ) , selection . end ( ) , flags ) ; } } }
Apply this effect to the selection.
If value is Null then the effect will be removed from the current selection.

@param editor The editor to apply the effect to (current selection)
@param value  The value to apply (depends on the Effect)
Apply this effect to the selection . If value is Null then the effect will be removed from the current selection .