diff --git a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/views/textinput/ReactEditText.kt b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/views/textinput/ReactEditText.kt index 5858f865273f..73b4de50289a 100644 --- a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/views/textinput/ReactEditText.kt +++ b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/views/textinput/ReactEditText.kt @@ -32,6 +32,8 @@ import android.text.TextUtils import android.text.TextWatcher import android.text.method.KeyListener import android.text.method.QwertyKeyListener +import android.text.style.CharacterStyle +import android.text.style.ParagraphStyle import android.util.TypedValue import android.view.ActionMode import android.view.DragEvent @@ -1242,6 +1244,12 @@ public open class ReactEditText public constructor(context: Context) : AppCompat } catch (e: IndexOutOfBoundsException) { logSoftException(TAG, e) } + // The copy only feeds measurement, so drop editor bookkeeping spans. Some of them reference + // this view's Editable (PasswordTransformationMethod.Visible), and the cache is evicted only + // from finalize(), so keeping them would keep this view reachable for good. + stripSpansOfKind(sb, Any::class.java) { span -> + span !is CharacterStyle && span !is ParagraphStyle && span !is ReactSpan + } } // If we don't have text, make sure we have *something* to measure.