Skip to content

Commit 67eb8dd

Browse files
committed
Fix ClassCastException in clearFocusAndMaybeRefocus when EditText is detached
On Android <= 9 (SDK_INT <= P) in touch mode, clearFocusAndMaybeRefocus casts rootView to ViewGroup unconditionally. getRootView() returns the view itself when the view is detached from the window, so an IME editor action delivered over Binder that races the removal of the EditText from the hierarchy crashes the app with: java.lang.ClassCastException: com.facebook.react.views.textinput.ReactEditText cannot be cast to android.view.ViewGroup Use a safe cast and fall back to a plain clearFocus(): when the view is already detached there is no focus to move, so the descendant-focusability workaround is not needed.
1 parent dfab628 commit 67eb8dd

1 file changed

Lines changed: 14 additions & 5 deletions

File tree

  • packages/react-native/ReactAndroid/src/main/java/com/facebook/react/views/textinput

packages/react-native/ReactAndroid/src/main/java/com/facebook/react/views/textinput/ReactEditText.kt

Lines changed: 14 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -380,11 +380,20 @@ public open class ReactEditText public constructor(context: Context) : AppCompat
380380
// Avoid refocusing to a new view on old versions of Android by default
381381
// by preventing `requestFocus()` on the rootView from moving focus to any child.
382382
// https://cs.android.com/android/_/android/platform/frameworks/base/+/bdc66cb5a0ef513f4306edf9156cc978b08e06e4
383-
val rootViewGroup = rootView as ViewGroup
384-
val oldDescendantFocusability = rootViewGroup.descendantFocusability
385-
rootViewGroup.descendantFocusability = ViewGroup.FOCUS_BLOCK_DESCENDANTS
386-
super.clearFocus()
387-
rootViewGroup.descendantFocusability = oldDescendantFocusability
383+
//
384+
// getRootView() returns the view itself when it is detached from the window, so the root
385+
// is not necessarily a ViewGroup: an IME editor action delivered over Binder can race the
386+
// removal of this view from the hierarchy. There is no focus to move in that case, so a
387+
// plain clearFocus() is enough.
388+
val rootViewGroup = rootView as? ViewGroup
389+
if (rootViewGroup != null) {
390+
val oldDescendantFocusability = rootViewGroup.descendantFocusability
391+
rootViewGroup.descendantFocusability = ViewGroup.FOCUS_BLOCK_DESCENDANTS
392+
super.clearFocus()
393+
rootViewGroup.descendantFocusability = oldDescendantFocusability
394+
} else {
395+
super.clearFocus()
396+
}
388397
}
389398
hideSoftKeyboard()
390399
}

0 commit comments

Comments
 (0)