diff --git a/ReactAndroid/src/main/java/com/facebook/react/uimanager/UIManagerHelper.java b/ReactAndroid/src/main/java/com/facebook/react/uimanager/UIManagerHelper.java index 8384d767007be8..295f45c19ce57d 100644 --- a/ReactAndroid/src/main/java/com/facebook/react/uimanager/UIManagerHelper.java +++ b/ReactAndroid/src/main/java/com/facebook/react/uimanager/UIManagerHelper.java @@ -9,8 +9,12 @@ import static com.facebook.react.uimanager.common.UIManagerType.FABRIC; import static com.facebook.react.uimanager.common.ViewUtil.getUIManagerType; -import com.facebook.react.bridge.CatalystInstance; + +import android.content.Context; +import android.content.ContextWrapper; +import android.view.View; import androidx.annotation.Nullable; +import com.facebook.react.bridge.CatalystInstance; import com.facebook.react.bridge.JSIModuleType; import com.facebook.react.bridge.ReactContext; import com.facebook.react.bridge.ReactSoftException; @@ -65,4 +69,20 @@ public static EventDispatcher getEventDispatcher( UIManager uiManager = getUIManager(context, uiManagerType); return uiManager == null ? null : (EventDispatcher) uiManager.getEventDispatcher(); } + + /** + * @return The {@link ReactContext} associated to the {@link View} received as a parameter. + *
We can't rely that the method View.getContext() will return the same context that was + * passed as a parameter during the construction of the View. + *
For example the AppCompatEditText class wraps the context received as a parameter in the + * constructor of the View into a TintContextWrapper object. See: + * https://android.googlesource.com/platform/frameworks/support/+/dd55716/v7/appcompat/src/android/support/v7/widget/AppCompatEditText.java#55 + */ + public static ReactContext getReactContext(View view) { + Context context = view.getContext(); + if (!(context instanceof ReactContext) && context instanceof ContextWrapper) { + context = ((ContextWrapper) context).getBaseContext(); + } + return (ReactContext) context; + } } diff --git a/ReactAndroid/src/main/java/com/facebook/react/views/textinput/ReactEditText.java b/ReactAndroid/src/main/java/com/facebook/react/views/textinput/ReactEditText.java index 81b8cb87da9457..67b4c1aa702330 100644 --- a/ReactAndroid/src/main/java/com/facebook/react/views/textinput/ReactEditText.java +++ b/ReactAndroid/src/main/java/com/facebook/react/views/textinput/ReactEditText.java @@ -7,6 +7,8 @@ package com.facebook.react.views.textinput; +import static com.facebook.react.uimanager.UIManagerHelper.getReactContext; + import android.content.Context; import android.graphics.Rect; import android.graphics.Typeface; @@ -114,7 +116,7 @@ public ReactEditText(Context context) { mReactBackgroundManager = new ReactViewBackgroundManager(this); mInputMethodManager = (InputMethodManager) - Assertions.assertNotNull(getContext().getSystemService(Context.INPUT_METHOD_SERVICE)); + Assertions.assertNotNull(context.getSystemService(Context.INPUT_METHOD_SERVICE)); mDefaultGravityHorizontal = getGravity() & (Gravity.HORIZONTAL_GRAVITY_MASK | Gravity.RELATIVE_HORIZONTAL_GRAVITY_MASK); mDefaultGravityVertical = getGravity() & Gravity.VERTICAL_GRAVITY_MASK; @@ -219,7 +221,7 @@ protected void onScrollChanged(int horiz, int vert, int oldHoriz, int oldVert) { @Override public InputConnection onCreateInputConnection(EditorInfo outAttrs) { - ReactContext reactContext = (ReactContext) getContext(); + ReactContext reactContext = getReactContext(this); InputConnection inputConnection = super.onCreateInputConnection(outAttrs); if (inputConnection != null && mOnKeyPress) { inputConnection = @@ -601,7 +603,7 @@ private void setIntrinsicContentSize() { // Since the LocalData object is constructed by getting values from the underlying EditText // view, we don't need to construct one or apply it at all - it provides no use in Fabric. if (mStateWrapper == null) { - ReactContext reactContext = (ReactContext) getContext(); + ReactContext reactContext = getReactContext(this); final ReactTextInputLocalData localData = new ReactTextInputLocalData(this); UIManagerModule uiManager = reactContext.getNativeModule(UIManagerModule.class); uiManager.setViewLocalData(getId(), localData); diff --git a/ReactAndroid/src/main/java/com/facebook/react/views/textinput/ReactTextInputManager.java b/ReactAndroid/src/main/java/com/facebook/react/views/textinput/ReactTextInputManager.java index d614989a3e7036..ba055c292aa92b 100644 --- a/ReactAndroid/src/main/java/com/facebook/react/views/textinput/ReactTextInputManager.java +++ b/ReactAndroid/src/main/java/com/facebook/react/views/textinput/ReactTextInputManager.java @@ -7,6 +7,8 @@ package com.facebook.react.views.textinput; +import static com.facebook.react.uimanager.UIManagerHelper.getReactContext; + import android.graphics.PorterDuff; import android.graphics.drawable.Drawable; import android.os.Build; @@ -1056,7 +1058,7 @@ private class ReactContentSizeWatcher implements ContentSizeWatcher { public ReactContentSizeWatcher(ReactEditText editText) { mEditText = editText; - ReactContext reactContext = (ReactContext) editText.getContext(); + ReactContext reactContext = getReactContext(editText); mEventDispatcher = reactContext.getNativeModule(UIManagerModule.class).getEventDispatcher(); } @@ -1099,7 +1101,8 @@ private class ReactSelectionWatcher implements SelectionWatcher { public ReactSelectionWatcher(ReactEditText editText) { mReactEditText = editText; - ReactContext reactContext = (ReactContext) editText.getContext(); + + ReactContext reactContext = getReactContext(editText); mEventDispatcher = reactContext.getNativeModule(UIManagerModule.class).getEventDispatcher(); } @@ -1133,7 +1136,7 @@ private class ReactScrollWatcher implements ScrollWatcher { public ReactScrollWatcher(ReactEditText editText) { mReactEditText = editText; - ReactContext reactContext = (ReactContext) editText.getContext(); + ReactContext reactContext = getReactContext(editText); mEventDispatcher = reactContext.getNativeModule(UIManagerModule.class).getEventDispatcher(); }