mirror of
https://github.com/facebook/react-native.git
synced 2025-11-01 09:14:26 +00:00
Implement JS Responder Handler in Fabric Android
Summary: This diff implements the JSResponderHandler in Fabric Android code Reviewed By: JoshuaGross Differential Revision: D16543438 fbshipit-source-id: 13680f77a5368e8ba1180383a5f9fb7d7330b90a
This commit is contained in:
committed by
Facebook Github Bot
parent
08e4537680
commit
0e067fd23b
@@ -569,11 +569,32 @@ public class FabricUIManager implements UIManager, LifecycleEventListener {
|
||||
@DoNotStrip
|
||||
public void setJSResponder(
|
||||
final int reactTag, final int initialReactTag, final boolean blockNativeResponder) {
|
||||
// do nothing for now.
|
||||
synchronized (mMountItemsLock) {
|
||||
mMountItems.add(
|
||||
new MountItem() {
|
||||
@Override
|
||||
public void execute(MountingManager mountingManager) {
|
||||
mountingManager.setJSResponder(reactTag, initialReactTag, blockNativeResponder);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Clears the JS Responder specified by {@link #setJSResponder(int, int, boolean)}. After this
|
||||
* method is called, all the touch events are going to be handled by JS.
|
||||
*/
|
||||
@DoNotStrip
|
||||
public void clearJSResponder() {
|
||||
// do nothing for now.
|
||||
synchronized (mMountItemsLock) {
|
||||
mMountItems.add(
|
||||
new MountItem() {
|
||||
@Override
|
||||
public void execute(MountingManager mountingManager) {
|
||||
mountingManager.clearJSResponder();
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -17,10 +17,12 @@ import com.facebook.infer.annotation.Assertions;
|
||||
import com.facebook.react.bridge.ReadableArray;
|
||||
import com.facebook.react.bridge.ReadableMap;
|
||||
import com.facebook.react.bridge.ReadableNativeMap;
|
||||
import com.facebook.react.bridge.SoftAssertions;
|
||||
import com.facebook.react.bridge.UiThreadUtil;
|
||||
import com.facebook.react.fabric.FabricUIManager;
|
||||
import com.facebook.react.fabric.events.EventEmitterWrapper;
|
||||
import com.facebook.react.fabric.mounting.mountitems.MountItem;
|
||||
import com.facebook.react.touch.JSResponderHandler;
|
||||
import com.facebook.react.uimanager.IllegalViewOperationException;
|
||||
import com.facebook.react.uimanager.ReactStylesDiffMap;
|
||||
import com.facebook.react.uimanager.RootView;
|
||||
@@ -40,6 +42,7 @@ import java.util.concurrent.ConcurrentHashMap;
|
||||
public class MountingManager {
|
||||
|
||||
private final ConcurrentHashMap<Integer, ViewState> mTagToViewState;
|
||||
private final JSResponderHandler mJSResponderHandler = new JSResponderHandler();
|
||||
private final ViewManagerRegistry mViewManagerRegistry;
|
||||
private final RootViewManager mRootViewManager = new RootViewManager();
|
||||
|
||||
@@ -183,7 +186,9 @@ public class MountingManager {
|
||||
if (isLayoutable) {
|
||||
viewManager = mViewManagerRegistry.get(componentName);
|
||||
// View Managers are responsible for dealing with initial state and props.
|
||||
view = viewManager.createView(themedReactContext, propsDiffMap, stateWrapper, null);
|
||||
view =
|
||||
viewManager.createView(
|
||||
themedReactContext, propsDiffMap, stateWrapper, mJSResponderHandler);
|
||||
view.setId(reactTag);
|
||||
}
|
||||
|
||||
@@ -329,6 +334,59 @@ public class MountingManager {
|
||||
viewState.mEventEmitter = eventEmitter;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the JS responder for the view associated with the tags received as a parameter.
|
||||
*
|
||||
* <p>The JSResponder coordinates the return values of the onInterceptTouch method in Android
|
||||
* Views. This allows JS to coordinate when a touch should be handled by JS or by the Android
|
||||
* native views. See {@link JSResponderHandler} for more details.
|
||||
*
|
||||
* <p>This method is going to be executed on the UIThread as soon as it is delivered from JS to
|
||||
* RN.
|
||||
*
|
||||
* <p>Currently, there is no warranty that the view associated with the react tag exists, because
|
||||
* this method is not handled by the react commit process.
|
||||
*
|
||||
* @param reactTag React tag of the first parent of the view that is NOT virtual
|
||||
* @param initialReactTag React tag of the JS view that initiated the touch operation
|
||||
* @param blockNativeResponder If native responder should be blocked or not
|
||||
*/
|
||||
@UiThread
|
||||
public synchronized void setJSResponder(
|
||||
int reactTag, int initialReactTag, boolean blockNativeResponder) {
|
||||
if (!blockNativeResponder) {
|
||||
mJSResponderHandler.setJSResponder(initialReactTag, null);
|
||||
return;
|
||||
}
|
||||
|
||||
ViewState viewState = getViewState(reactTag);
|
||||
View view = viewState.mView;
|
||||
if (initialReactTag != reactTag && view instanceof ViewParent) {
|
||||
// In this case, initialReactTag corresponds to a virtual/layout-only View, and we already
|
||||
// have a parent of that View in reactTag, so we can use it.
|
||||
mJSResponderHandler.setJSResponder(initialReactTag, (ViewParent) view);
|
||||
return;
|
||||
} else if (view == null) {
|
||||
SoftAssertions.assertUnreachable("Cannot find view for tag " + reactTag + ".");
|
||||
return;
|
||||
}
|
||||
|
||||
if (viewState.mIsRoot) {
|
||||
SoftAssertions.assertUnreachable(
|
||||
"Cannot block native responder on " + reactTag + " that is a root view");
|
||||
}
|
||||
mJSResponderHandler.setJSResponder(initialReactTag, view.getParent());
|
||||
}
|
||||
|
||||
/**
|
||||
* Clears the JS Responder specified by {@link #setJSResponder(int, int, boolean)}. After this
|
||||
* method is called, all the touch events are going to be handled by JS.
|
||||
*/
|
||||
@UiThread
|
||||
public void clearJSResponder() {
|
||||
mJSResponderHandler.clearJSResponder();
|
||||
}
|
||||
|
||||
@AnyThread
|
||||
public long measure(
|
||||
Context context,
|
||||
|
||||
Reference in New Issue
Block a user