This answer by @Taylor Clark was pretty informative. However, it wasn’t an actual sharing of experience with using the single-activity approach as I asked in my original question. I set out to modify the News Reader example from the Android developer guide to use the single-activity approach and came up with a workable solution.
What remains to be seen is what are the use cases where this approach is preferable over the multiple-activity method (or whether there are any such cases at all). Also, I haven’t looked in detail about the 3-pane scenario described in Edit 1 of my question.
I hope to post my entire project shortly, but here is a quick overview of how I went about it:
- Single
Activity: NewsActivity - Two Fragments:
TitlesListFragmentandDetailsFragment - Both fragments are always present in
NewsActivity. Depending on the current dual-pane-ness, I show/hide the appropriate fragment.
Some problems I came across:
Designating a Layout as Dual-pane or not:
In the original News Reader example, dual-pane layouts have a FrameLayout for holding the news Details. We figure out whether we are currently in a dual-pane layout by testing for the existence of this Frame Layout.
However, in my solution, both fragments are always present in all layouts. I hacked this by including a View with id dualPane and android:visibility="gone" in those layouts that I want to be dual-pane and omitting this view in the single-pane layout. Then, it was a matter of
mDualPane = findViewById(R.id.dualPane)!=null;
EDIT:
There are better ways to designate dual pane-ness than having a dummy view. The one I prefer is to create a boolean resource. For example, I have a config.xml as follows:
<resources>
<bool name="dual_pane">false</bool>
</resources>
I can then place additional config.xml files in folders like values-xlarge-land, values-port or values-sw600dp etc and adjust the boolean value to true or false as I desire.
Then, in the code it is a matter of getResources().getBoolean(R.bool.dual_pane);
Closing the Details Fragment
This was a problem of differentiating between the Activity close and the Fragment close. In the end, I had to override onBackPressed() as follows:
- In dual-pane mode, just call
super.onBackPressed(); - In single-pane mode, if we are in
TitlesListFragment, callsuper.onBackPressed(); - In single-pane mode, if we are in
DetailsFragment, then treat it as closing the fragment. This means hiding it and showing theTitlesListFragment.
This is not ideal, but it is the best I could come up with.
EDIT:
Based on the suggestion by @SherifelKhatib in the comments, there is a much cleaner way to handle back-button presses: Simply add to the Fragment backstack, the transaction of showing/hiding the details fragment. That way, when you press the back button, the fragment transaction is reversed. You can also pop the backstack manually if you wish to do so on other button clicks.