Files
react-native/ReactAndroid/src/main/java/com/facebook/react/uimanager/UIManagerHelper.java
T
David Vacca a8fbbe2350 Fix rendering of TextInput in Android 4
Summary:
This diff fixes the rendering of TextInput component for Android 4 devices.
This bug was caused by D18196901, when we changed the base class of ReactEditText from EditText to AppCompatEditText.
The root of the problem is that AppCompatEditText wraps the ReactContext received as a parameter in the construction of the View into a ContextWrapper object. This break the implicity assumption that the method View.getContext will return the same context that was used during the construction of the view.
https://android.googlesource.com/platform/frameworks/support/+/dd55716/v7/appcompat/src/android/support/v7/widget/AppCompatEditText.java#55

Changelog: [internal]

Reviewed By: ejanzer

Differential Revision: D19204032

fbshipit-source-id: eefb562b1da22e6cc58c75845c87dd032d727f49
2019-12-20 17:27:53 -08:00

89 lines
3.6 KiB
Java

/*
* Copyright (c) Facebook, Inc. and its affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/
package com.facebook.react.uimanager;
import static com.facebook.react.uimanager.common.UIManagerType.FABRIC;
import static com.facebook.react.uimanager.common.ViewUtil.getUIManagerType;
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;
import com.facebook.react.bridge.UIManager;
import com.facebook.react.uimanager.common.UIManagerType;
import com.facebook.react.uimanager.events.EventDispatcher;
/** Helper class for {@link UIManager}. */
public class UIManagerHelper {
/** @return a {@link UIManager} that can handle the react tag received by parameter. */
@Nullable
public static UIManager getUIManagerForReactTag(ReactContext context, int reactTag) {
return getUIManager(context, getUIManagerType(reactTag));
}
/** @return a {@link UIManager} that can handle the react tag received by parameter. */
@Nullable
public static UIManager getUIManager(ReactContext context, @UIManagerType int uiManagerType) {
if (context.isBridgeless()) {
return (UIManager) context.getJSIModule(JSIModuleType.UIManager);
} else {
if (!context.hasActiveCatalystInstance()) {
ReactSoftException.logSoftException(
"UIManagerHelper",
new RuntimeException("Cannot get UIManager: no active Catalyst instance"));
return null;
}
CatalystInstance catalystInstance = context.getCatalystInstance();
return uiManagerType == FABRIC
? (UIManager) catalystInstance.getJSIModule(JSIModuleType.UIManager)
: catalystInstance.getNativeModule(UIManagerModule.class);
}
}
/**
* @return the {@link EventDispatcher} that handles events for the reactTag received as a
* parameter.
*/
@Nullable
public static EventDispatcher getEventDispatcherForReactTag(ReactContext context, int reactTag) {
return getEventDispatcher(context, getUIManagerType(reactTag));
}
/**
* @return the {@link EventDispatcher} that handles events for the {@link UIManagerType} received
* as a parameter.
*/
@Nullable
public static EventDispatcher getEventDispatcher(
ReactContext context, @UIManagerType int uiManagerType) {
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.
* <p>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.
* <p>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;
}
}