diff --git a/e2e/Modals.test.js b/e2e/Modals.test.js
index 110c3ec00ff..b5e33dc5409 100644
--- a/e2e/Modals.test.js
+++ b/e2e/Modals.test.js
@@ -118,6 +118,12 @@ describe('modal', () => {
await expect(elementByLabel('Modal Stack Position: 1')).toBeVisible();
});
+ it('setRoot dismisses modals', async () => {
+ await elementById(TestIDs.SET_ROOT).tap();
+ await expect(elementById(TestIDs.MODAL_SCREEN_HEADER)).toBeNotVisible();
+ await expect(elementById(TestIDs.PUSHED_SCREEN_HEADER)).toBeVisible();
+ });
+
it(':android: override hardware back button in modal with stack', async () => {
await elementById(TestIDs.PUSH_BTN).tap();
await elementById(TestIDs.ADD_BACK_HANDLER).tap();
diff --git a/lib/android/app/src/main/java/com/reactnativenavigation/viewcontrollers/navigator/Navigator.java b/lib/android/app/src/main/java/com/reactnativenavigation/viewcontrollers/navigator/Navigator.java
index 82ec475945c..12c264bb531 100644
--- a/lib/android/app/src/main/java/com/reactnativenavigation/viewcontrollers/navigator/Navigator.java
+++ b/lib/android/app/src/main/java/com/reactnativenavigation/viewcontrollers/navigator/Navigator.java
@@ -50,7 +50,7 @@ public Options getDefaultOptions() {
return defaultOptions;
}
- public FrameLayout getRootLayout() {
+ FrameLayout getRootLayout() {
return rootLayout;
}
@@ -129,6 +129,7 @@ public void sendOnNavigationButtonPressed(String buttonId) {
public void setRoot(final ViewController viewController, CommandListener commandListener, ReactInstanceManager reactInstanceManager) {
destroyRoot();
+ modalStack.destroy();
final boolean removeSplashView = isRootNotCreated();
if (isRootNotCreated()) getView();
root = viewController;
@@ -138,11 +139,11 @@ public void onSuccess(String childId) {
if (removeSplashView) removePreviousContentView();
super.onSuccess(childId);
}
- }, reactInstanceManager);
- }
- private void removePreviousContentView() {
- contentLayout.removeViewAt(0);
+ private void removePreviousContentView() {
+ contentLayout.removeViewAt(0);
+ }
+ }, reactInstanceManager);
}
public void mergeOptions(final String componentId, Options options) {
diff --git a/lib/android/app/src/test/java/com/reactnativenavigation/viewcontrollers/navigator/NavigatorTest.java b/lib/android/app/src/test/java/com/reactnativenavigation/viewcontrollers/navigator/NavigatorTest.java
index aaf890cbf58..bfbc3ca6ab5 100644
--- a/lib/android/app/src/test/java/com/reactnativenavigation/viewcontrollers/navigator/NavigatorTest.java
+++ b/lib/android/app/src/test/java/com/reactnativenavigation/viewcontrollers/navigator/NavigatorTest.java
@@ -47,6 +47,7 @@
import java.util.List;
import static org.assertj.core.api.Java6Assertions.assertThat;
+import static org.junit.Assert.assertTrue;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.Mockito.spy;
@@ -166,6 +167,13 @@ public void setRoot_ReplacesExistingChildControllerViews() {
assertIsChild(uut.getRootLayout(), child2.getView());
}
+ @Test
+ public void setRoot_destroysModals() {
+ uut.showModal(child1, new CommandListenerAdapter());
+ uut.setRoot(child2, new CommandListenerAdapter(), reactInstanceManager);
+ assertTrue(child1.isDestroyed());
+ }
+
@Test
public void hasUniqueId() {
assertThat(uut.getId()).startsWith("navigator");
diff --git a/playground/src/screens/ModalScreen.js b/playground/src/screens/ModalScreen.js
index 6d1dc1d98f8..90d3f274fa1 100644
--- a/playground/src/screens/ModalScreen.js
+++ b/playground/src/screens/ModalScreen.js
@@ -3,6 +3,7 @@ const React = require('react');
const Root = require('../components/Root');
const Button = require('../components/Button')
const Navigation = require('./../services/Navigation');
+const { stack } = require('../commons/Layouts');
const Screens = require('./Screens');
const {
PUSH_BTN,
@@ -15,6 +16,7 @@ const {
DISMISS_ALL_PREVIOUS_MODAL_BTN,
DISMISS_ALL_MODALS_BTN,
DISMISS_FIRST_MODAL_BTN,
+ SET_ROOT
} = require('../testIDs');
class ModalScreen extends React.Component {
@@ -46,6 +48,7 @@ class ModalScreen extends React.Component {
{this.props.previousModalIds && ()}
+
);
}
@@ -83,6 +86,8 @@ class ModalScreen extends React.Component {
pushScreen = () => Navigation.push(this, Screens.Pushed);
+ setRoot = () => Navigation.setRoot(stack(Screens.Pushed));
+
getModalPosition = () => this.props.modalPosition || 1;
getPreviousModalId = () => _.last(this.props.previousModalIds);
diff --git a/playground/src/services/Navigation.js b/playground/src/services/Navigation.js
index 41ea3720520..a16bc76e142 100644
--- a/playground/src/services/Navigation.js
+++ b/playground/src/services/Navigation.js
@@ -27,7 +27,9 @@ const popToRoot = (self) => Navigation.popToRoot(self.props.componentId);
const mergeOptions = (selfOrCompId, options) => Navigation.mergeOptions(compId(selfOrCompId), options);
-const setStackRoot = (self, root) => Navigation.setStackRoot(self.props.componentId, root)
+const setStackRoot = (self, root) => Navigation.setStackRoot(self.props.componentId, root);
+
+const setRoot = (root) => Navigation.setRoot(root.root ? root : { root: component(root, {}) });
const compId = (selfOrCompId) => {
return get(selfOrCompId, 'props.componentId', selfOrCompId);
@@ -49,7 +51,7 @@ module.exports = {
events: Navigation.events.bind(Navigation),
popTo: Navigation.popTo.bind(Navigation),
setDefaultOptions: Navigation.setDefaultOptions.bind(Navigation),
- setRoot: Navigation.setRoot.bind(Navigation),
+ setRoot,
TouchablePreview: Navigation.TouchablePreview,
setStackRoot,
constants
diff --git a/playground/src/testIDs.js b/playground/src/testIDs.js
index 8c36303a7ff..0d51f306543 100644
--- a/playground/src/testIDs.js
+++ b/playground/src/testIDs.js
@@ -125,6 +125,7 @@ module.exports = {
SET_INTERCEPT_TOUCH: `SET_INTERCEPT_TOUCH`,
PUSH_BOTTOM_TABS_BUTTON: `PUSH_BOTTOM_TABS_BUTTON`,
SET_STACK_ROOT_BUTTON: `SET_STACK_ROOT_BUTTON`,
+ SET_ROOT:'SET_ROOT',
// Elements
SCROLLVIEW_ELEMENT: `SCROLLVIEW_ELEMENT`,