Files
react-navigation/android/src/main/java/com/swmansion/rnscreens/ScreenViewManager.java
Janic Duplessis d32463ee83 Move gestureEnabled config to screen instead of heade… (#254)
When you have 2 screens in a stack with the bottom one with gestureEnabled=false using the back gesture causes the screen to become unresponsive. This seems to be caused by setting interactivePopGestureRecognizer.enabled = NO as soon as the gesture starts. This causes the gesture to cancel immediately and leaves the screen in an unresponsive state.

<Stack><Screen gestureEnabled={false} /><Screen /></Stack>
To fix this instead of using interactivePopGestureRecognizer.enabled we can leverage the existing delegate that we have in RNScreenStack. In gestureRecognizerShouldBegin we can check if the top screen has gestures enabled.

To make this simpler I moved the gestureEnabled config to Screen instead of HeaderConfig. I think it also makes more sense conceptually since the gesture is tied to the screen and not the header. It also simplifies the android code a bit.

This is a breaking change.

Update

This now only moves the config to screen since a separate fix was merged for the bug.
2020-01-24 01:19:38 +01:00

75 lines
2.7 KiB
Java

package com.swmansion.rnscreens;
import com.facebook.react.bridge.JSApplicationIllegalArgumentException;
import com.facebook.react.common.MapBuilder;
import com.facebook.react.module.annotations.ReactModule;
import com.facebook.react.uimanager.ThemedReactContext;
import com.facebook.react.uimanager.ViewGroupManager;
import com.facebook.react.uimanager.annotations.ReactProp;
import java.util.Map;
import javax.annotation.Nullable;
@ReactModule(name = ScreenViewManager.REACT_CLASS)
public class ScreenViewManager extends ViewGroupManager<Screen> {
protected static final String REACT_CLASS = "RNSScreen";
@Override
public String getName() {
return REACT_CLASS;
}
@Override
protected Screen createViewInstance(ThemedReactContext reactContext) {
return new Screen(reactContext);
}
@ReactProp(name = "active", defaultFloat = 0)
public void setActive(Screen view, float active) {
view.setActive(active != 0);
}
@ReactProp(name = "stackPresentation")
public void setStackPresentation(Screen view, String presentation) {
if ("push".equals(presentation)) {
view.setStackPresentation(Screen.StackPresentation.PUSH);
} else if ("modal".equals(presentation) || "containedModal".equals(presentation)) {
// at the moment Android implementation does not handle contained vs regular modals
view.setStackPresentation(Screen.StackPresentation.MODAL);
} else if ("transparentModal".equals(presentation) || "containedTransparentModal".equals((presentation))) {
// at the moment Android implementation does not handle contained vs regular modals
view.setStackPresentation(Screen.StackPresentation.TRANSPARENT_MODAL);
} else {
throw new JSApplicationIllegalArgumentException("Unknown presentation type " + presentation);
}
}
@ReactProp(name = "stackAnimation")
public void setStackAnimation(Screen view, String animation) {
if (animation == null || "default".equals(animation)) {
view.setStackAnimation(Screen.StackAnimation.DEFAULT);
} else if ("none".equals(animation)) {
view.setStackAnimation(Screen.StackAnimation.NONE);
} else if ("fade".equals(animation)) {
view.setStackAnimation(Screen.StackAnimation.FADE);
}
}
@ReactProp(name = "gestureEnabled", defaultBoolean = true)
public void setGestureEnabled(Screen view, boolean gestureEnabled) {
view.setGestureEnabled(gestureEnabled);
}
@Nullable
@Override
public Map getExportedCustomDirectEventTypeConstants() {
return MapBuilder.of(
ScreenDismissedEvent.EVENT_NAME,
MapBuilder.of("registrationName", "onDismissed"),
ScreenAppearEvent.EVENT_NAME,
MapBuilder.of("registrationName", "onAppear"));
}
}