diff --git a/conductor/src/main/java/com/bluelinelabs/conductor/Controller.java b/conductor/src/main/java/com/bluelinelabs/conductor/Controller.java index 5ccfa9a9..9992f98b 100644 --- a/conductor/src/main/java/com/bluelinelabs/conductor/Controller.java +++ b/conductor/src/main/java/com/bluelinelabs/conductor/Controller.java @@ -761,8 +761,8 @@ final void setNeedsAttach(boolean needsAttach) { this.needsAttach = needsAttach; } - final void prepareForHostDetach() { - needsAttach = needsAttach || attached; + final void prepareForHostDetach(boolean wasAttached) { + needsAttach = wasAttached; for (ControllerHostedRouter router : childRouters) { router.prepareForHostDetach(); diff --git a/conductor/src/main/java/com/bluelinelabs/conductor/Router.java b/conductor/src/main/java/com/bluelinelabs/conductor/Router.java index 024b3d70..8a635d1b 100644 --- a/conductor/src/main/java/com/bluelinelabs/conductor/Router.java +++ b/conductor/src/main/java/com/bluelinelabs/conductor/Router.java @@ -632,12 +632,11 @@ public void onActivityDestroyed(@NonNull Activity activity) { public void prepareForHostDetach() { pendingControllerChanges.clear(); // rely on backstack based restoration in rebindIfNeeded + boolean needsAttach = true; for (RouterTransaction transaction : backstack) { - if (ControllerChangeHandler.completeHandlerImmediately(transaction.controller().getInstanceId())) { - transaction.controller().setNeedsAttach(true); - } - - transaction.controller().prepareForHostDetach(); + ControllerChangeHandler.completeHandlerImmediately(transaction.controller().getInstanceId()); + transaction.controller().prepareForHostDetach(needsAttach); + needsAttach = transaction.pushChangeHandler() != null && !transaction.pushChangeHandler().removesFromViewOnPush(); } } diff --git a/conductor/src/test/java/com/bluelinelabs/conductor/RouterTests.java b/conductor/src/test/java/com/bluelinelabs/conductor/RouterTests.java index df4b062d..99ea9850 100644 --- a/conductor/src/test/java/com/bluelinelabs/conductor/RouterTests.java +++ b/conductor/src/test/java/com/bluelinelabs/conductor/RouterTests.java @@ -493,4 +493,40 @@ public void preDestroyView(@NonNull Controller controller, @NonNull View view) { assertTrue(controller3.isBeingDestroyed()); } + @Test + public void testReattachNestedBackstackCorrectly() { + Controller rootController = new TestController(); + Controller childController1 = new TestController(); + Controller childController2 = new TestController(); + Controller childController11 = new TestController(); + Controller childController12 = new TestController(); + Controller childController13 = new TestController(); + + + router.setRoot(RouterTransaction.with(rootController)); + Router router1 = rootController.getChildRouter(rootController.getView().findViewById(TestController.CHILD_VIEW_ID_1)); + router1.setRoot(RouterTransaction.with(childController1)); + Router router2 = childController1.getChildRouter(childController1.getView().findViewById(TestController.CHILD_VIEW_ID_1)); + router2.setRoot(RouterTransaction.with(childController11)); + router2.pushController(RouterTransaction.with(childController12).pushChangeHandler(new HorizontalChangeHandler()).popChangeHandler(new HorizontalChangeHandler())); + router2.pushController(RouterTransaction.with(childController13).pushChangeHandler(new HorizontalChangeHandler()).popChangeHandler(new HorizontalChangeHandler())); + router1.pushController(RouterTransaction.with(childController2)); + + assertTrue(rootController.isAttached()); + assertFalse(childController1.isAttached()); + assertFalse(childController11.isAttached()); + assertFalse(childController12.isAttached()); + assertFalse(childController13.isAttached()); + assertTrue(childController2.isAttached()); + + assertTrue(router.handleBack()); + + assertTrue(rootController.isAttached()); + assertTrue(childController1.isAttached()); + assertFalse(childController11.isAttached()); + assertFalse(childController12.isAttached()); + assertTrue(childController13.isAttached()); + assertFalse(childController2.isAttached()); + } + }