Single Activity with several fragments, typical scenario. Struggle to achieve desired behavior
I have an application doing one activity with multiple (2) fragments at a given time. I have a snippet on the left that functions like a menu for which the snippet is on the right side.
As an example, we can say that the menu consists of different sports; Football, basketball, baseball, skiing, etc. When the user selects a sport, a snippet with detailed information about the specific sport is displayed on the right.
I've configured my app to display two fragments at once in layout and layout. However, in layout-layout, only one fragment is shown at the moment.
Imagine this; the user views the application in a small landscape layout (two fragments at a time) and selects sports, football. Soon after, he chooses Basketball. If he now wants to rotate to layout-layout (one chunk at a time), I want this:
The basketball slice should be visible, but if he hits the back button, it should go back to the menu and not the soccer (!) Slice, which is the previous slice in the background stack by default.
I currently solved it this way:
....
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
// static fragments
if(menuFragment == null) menuFragment = new MenuFragment();
if(baseFragment == null) baseFragment = new TimerFragment(); // default content fragment
FragmentTransaction ft = getSupportFragmentManager().beginTransaction();
ft.setTransition(FragmentTransaction.TRANSIT_FRAGMENT_OPEN);
// Determine what layout we're in..
if(app().getLayoutBehavior(this) == LayoutBehavior.SINGLE_FRAGMENT) {
// We are currently in single fragment mode
if(savedInstanceState != null) {
if(!rotateFromSingleToDual) {
// We just changed orientation from dual fragments to single fragment!
// Clear the entire fragment back stack
for(int i=0;i<getSupportFragmentManager().getBackStackEntryCount();i++) {
getSupportFragmentManager().popBackStack();
}
ft.replace(R.id.fragmentOne, menuFragment); // Add menu fragment at the bottom of the stack
ft.replace(R.id.fragmentOne, baseFragment);
ft.addToBackStack(null);
ft.commit();
}
rotateFromSingleToDual = true;
return;
}
rotateFromSingleToDual = true;
ft.replace(R.id.fragmentOne, menuFragment);
} else if(app().getLayoutBehavior(this) == LayoutBehavior.DUAL_FRAGMENTS) {
// We are now in dual fragments mode
if(savedInstanceState != null) {
if(rotateFromSingleToDual) {
// We just changed orientation from single fragment to dual fragments!
ft.replace(R.id.fragmentOne, menuFragment);
ft.replace(R.id.fragmentTwo, baseFragment);
ft.commit();
}
rotateFromSingleToDual = false;
return;
}
rotateFromSingleToDual = false;
ft.replace(R.id.fragmentOne, menuFragment);
ft.replace(R.id.fragmentTwo, baseFragment);
}
ft.commit();
}
This works at least from time to time. However, many times I get java.lang.IllegalStateException: Fragment already added: MenuFragment (....)
Can someone please give me some pointers on how best to implement this? My current code is not good at all, and I'm sure a lot of developers want to achieve exactly this.
Thanks in advance!
source to share
A common way to implement this scenario is to use the fragment stack only in a mode that shows multiple fragments. When you are in single chunk mode, you start a new activity and the only job is to display one chunk and use the stack of the previous activity.
In your case, you just need to remember the currently selected location when pivoting to set it as an argument when starting a new action.
It explained much better here: -
http://developer.android.com/guide/components/fragments.html
Hope it helps.
source to share