I have an Android App with a single activity. The activity contains a SlidingTabLayout with a ViewPageAdapter as in this example. Each tab contains a respective root fragment which I then replace with other fragments as the user uses that screen. A visual representation is shown below:
With my current implementation I do the following: go to tab1, the ProductListFragment immediately loads by replacing the ProductRootFragment with the ProductListFragment. I click on a product and it replaces the ProductListFragment with the ProductDetailFragment. Now I switch to tab2 and Tab2ListFragment immediately loads by replacing Tab2RootFragment. I click on an item and the Tab2DetailFragment replaces the Tab2ListFragment. I now return to Tab1 and, as I expect, ProductDetailFragment is still displayed. However, if I now click the back button, it doesn't take me back to ProductListFragment as I expect. Instead it pops off Tab2DetailFragment from the backstack.
I want to implement a separate backstack for each "tab" fragment. There are several posts about this already but they all seem to be outdated and some suggest very elaborate solutions. (See here, here and here...)
It seems that in the latest versions of the SDK Android can automatically handle this backstack hierarchy without the need to manually implement some kind of backstack by using getChildFragmentManager rather than getSupportFragmentManager in my transactions where I replace the fragments. I have, however, not been able to get this to work. (I intuitively feel that the correct solution lies along the lines of letting Android handle this as it feels like manually overriding the back button and implementing your own stack is an elaborate hack.)
Can someone please explain how to properly implement the expected behavior where a separate backstack is maintained for each tab? Or perhaps link to a simple, well-designed and up-to-date example of how to achieve the desired behavior?
Additional information about my code: In my MainActivity.java, I construct the ViewPagerAdapter using getSupportFragmentManager().
ViewPagerAdapter.java
@Override
public Fragment getItem(int position) {
switch(position){
case 0: return new ProductRootFragment();
...
}
...
}
ProductRootFragment.java
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.product_root_fragment, container, false);
FragmentTransaction transaction = getFragmentManager()
.beginTransaction();
transaction.replace(R.id.product_root_container, new ProductListFragment());
transaction.commit();
return view;
}
ProductListFragment.java
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View layout = inflater.inflate(R.layout.product_list_fragment, container, false);
view = (ProductListView) layout;
return view;
}
...
@Override
public void onListItemClick(ListView l, View v, int position, long id) {
...
ProductDetailFragment newFragment = new ProductDetailFragment();
FragmentTransaction transaction = getFragmentManager().beginTransaction();
transaction.replace(R.id.product_root_container, newFragment);
transaction.addToBackStack(null);
transaction.commit();
}
ProductDetailFragment.java
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
view = (ProductDetailView) inflater.inflate(R.layout.product_detail_fragment, container, false);
return view;
}