The example in the sample doesn't correctly survive configuration changes (you can get the portrait layout in landscape sometimes)

How should I be doing this? I've attempted to achieve this, but I am currently having issues restoring state.
I currently have the whole layout wrapped in a single HomeController, which has three childRouters via homeController.getChildRouter(view, TAG)
appBarRouternavDrawerRoutermasterRouter (represents the current nav drawer selection)masterRouter's root is masterControllerA (or masterControllerB when toggled by nav drawer). detailControllerA's is either:
masterRouter (in phone config, for single pane layout)masterController (in tablet config, for two pane layout)To avoid instantiating unnecessary controllers I'm always checking if the router/controller is already contained in the existing ViewGroup container/router by its tag.
Does any of this throw a red flag?
I've tried using a single dagger module with all routers/controllers in the same scope - but I hit this error when swapping nav drawer options (aka changing the root of the masterRouter
Caused by: java.lang.NullPointerException: Attempt to invoke virtual method 'java.util.List com.bluelinelabs.conductor.Controller.getChildRouters()' on a null object reference
at com.bluelinelabs.conductor.ControllerHostedRouter.getSiblingRouters(ControllerHostedRouter.java:187)
at com.bluelinelabs.conductor.Router.removeAllExceptVisibleAndUnowned(Router.java:711)
at com.bluelinelabs.conductor.Router.setRoot(Router.java:283)
I'm guessing it has something to do with swapping setting the root of the masterRouter while reusing the childRouter instance of a controller that was previously attached (but no longer attached) to the masterRouter
What's the problem with the way it's implemented in the demo app? The only time you can get the portrait layout in landscape is if you flip the phone when you're already in the detail view (I think). If there's another case I'm not aware of, please let me know.
Regarding your question, the only thing that throws a red flag is that it sounds like you're reusing potentially destroyed controllers. It all looks good besides that.
As for your crash, you're exactly right. If you try to use a Router that isn't attached to a host of any kind (ex: a child router whose controller isn't attached), you're not gonna have a good time.
The only time you can get the portrait layout in landscape is if you flip the phone when you're already in the detail view (I think)
Is this considered a bug? (I think it should be)
Yeah, it probably should be considered a bug. I just wrote that as a quick demo without giving it too much thought. I've never had to use a master/detail view for much - how do apps typically handle this case? The master/detail example created by Android Studio's new project wizard seems to do what the demo does.
how do apps typically handle this case
DetailController in portraitMasterController and DetailController are visible, with the sameDetailController active that was visible in portraitMy confusion stems around how I should be restoring the state of routers and controllers in a configuration change when you switch from portrait to landscape (single pane layout to two pane layout).
I see two general approaches:
Have a separate masterRouter and detailRouter for landscape. In portrait, there would only be one masterRouter, which the detailController would be pushed on to. The problem here is that the detailController will be in the masterRouter in portrait, but in the detailRouter in landscape).
A single masterRouter, which masterController gets the detailRouter as its child router. I think this approach is the recommended one, but I struggled with it for the following reason.
The demo utilizes a single, static masterController - like a navigation drawer, it's always there. My use case has a dynamic masterController, where I need to swap out the masterController based on the nav drawer selection. If you have used Google Play Music before, my use case is more like that. Think of how that app toggles between the two navigation drawer options, Home and Music Library, when the HomeFragment and MusicLibraryFragment would be two of the masterControllers, that each have their own separate detailFragment
@ZakTaccardi did you ever find a good solution to this?
I think currently there is no easy way to handle this in Conductor.
The workaround that I came up with is this:
I have an OverviewController which always has 2 child-routers for
MasterController (shows the list of items)DetailController (shows the selected item)landscape-layout is easy: MasterController and DetailController are shown side-by side (e.g. in a horizontal LinearLayout)
prortrait-layout needs more work
FrameLayout which will only show the MasterController or the DetailController@EricKuck I guess the issue is still valid and I've added my implementation just in case.
https://github.com/bluelinelabs/Conductor/pull/564
Most helpful comment
DetailControllerin portraitMasterControllerandDetailControllerare visible, with the sameDetailControlleractive that was visible in portraitMy confusion stems around how I should be restoring the state of routers and controllers in a configuration change when you switch from portrait to landscape (single pane layout to two pane layout).
I see two general approaches:
Have a separate
masterRouteranddetailRouterfor landscape. In portrait, there would only be onemasterRouter, which thedetailControllerwould be pushed on to. The problem here is that thedetailControllerwill be in themasterRouterin portrait, but in thedetailRouterin landscape).A single
masterRouter, whichmasterControllergets thedetailRouteras its child router. I think this approach is the recommended one, but I struggled with it for the following reason.The demo utilizes a single, static
masterController- like a navigation drawer, it's always there. My use case has a dynamicmasterController, where I need to swap out themasterControllerbased on the nav drawer selection. If you have used Google Play Music before, my use case is more like that. Think of how that app toggles between the two navigation drawer options, Home and Music Library, when theHomeFragmentandMusicLibraryFragmentwould be two of themasterControllers, that each have their own separatedetailFragment