@@ -308,6 +308,7 @@ private void change(int start, int end, CharSequence cs, int csStart, int csEnd)
308308 resizeFor (mText .length + nbNewChars - mGapLength );
309309 }
310310
311+ final boolean textIsRemoved = replacementLength == 0 ;
311312 // The removal pass needs to be done before the gap is updated in order to broadcast the
312313 // correct previous positions to the correct intersecting SpanWatchers
313314 if (replacedLength > 0 ) { // no need for span fixup on pure insertion
@@ -319,12 +320,15 @@ private void change(int start, int end, CharSequence cs, int csStart, int csEnd)
319320 while (i < mSpanCount ) {
320321 if ((mSpanFlags [i ] & Spanned .SPAN_EXCLUSIVE_EXCLUSIVE ) ==
321322 Spanned .SPAN_EXCLUSIVE_EXCLUSIVE &&
322- mSpanStarts [i ] >= start && mSpanStarts [i ] < mGapStart + mGapLength &&
323- mSpanEnds [i ] >= start && mSpanEnds [i ] < mGapStart + mGapLength ) {
323+ mSpanStarts [i ] >= start && mSpanStarts [i ] < mGapStart + mGapLength &&
324+ mSpanEnds [i ] >= start && mSpanEnds [i ] < mGapStart + mGapLength &&
325+ // This condition indicates that the span would become empty
326+ (textIsRemoved || mSpanStarts [i ] > start || mSpanEnds [i ] < mGapStart )) {
324327 removeSpan (i );
325- } else {
326- i ++;
328+ continue ; // do not increment i, spans will be shifted left in the array
327329 }
330+
331+ i ++;
328332 }
329333 }
330334
@@ -338,7 +342,6 @@ private void change(int start, int end, CharSequence cs, int csStart, int csEnd)
338342
339343 if (replacedLength > 0 ) { // no need for span fixup on pure insertion
340344 final boolean atEnd = (mGapStart + mGapLength == mText .length );
341- final boolean textIsRemoved = replacementLength == 0 ;
342345
343346 for (int i = 0 ; i < mSpanCount ; i ++) {
344347 final int startFlag = (mSpanFlags [i ] & START_MASK ) >> START_SHIFT ;
@@ -390,9 +393,9 @@ private int updatedIntervalBound(int offset, int start, int nbNewChars, int flag
390393 return mGapStart + mGapLength ;
391394 }
392395 } else { // MARK
393- // MARKs should be moved to the start, with the exception of a mark located at the
394- // end of the range (which will be < mGapStart + mGapLength since mGapLength > 0)
395- // which should stay 'unchanged' at the end of the replaced text.
396+ // MARKs should be moved to the start, with the exception of a mark located at
397+ // the end of the range (which will be < mGapStart + mGapLength since mGapLength
398+ // is > 0, which should stay 'unchanged' at the end of the replaced text.
396399 if (textIsRemoved || offset < mGapStart - nbNewChars ) {
397400 return start ;
398401 } else {
0 commit comments