I have an android application with one action. This activity contains a SlidingTabLayout with a ViewPageAdapter, as in this example. Each tab contains a corresponding root fragment, which is then replaced with other fragments when the user uses this screen. A visual representation is shown below:

In my current implementation, I do the following: go to tab1, ProductListFragment will load immediately, replacing ProductRootFragment with ProductListFragment. I click on a product and replace ProductListFragment with ProductDetailFragment. Now I switch to tab2 and Tab2ListFragment loads immediately, replacing Tab2RootFragment. I click on an element, and Tab2DetailFragment replaces Tab2ListFragment. Now I'm returning to Tab1 and, as I suppose, ProductDetailFragment is still displayed. However, if I click the back button now, it will not return me to ProductListFragment, as I expect. Instead, it pops a Tab2DetailFragment from the backstack.
I want to implement a separate freeze frame for each fragment of the "tab". There are several reports about this, but they all seem to be outdated, and some offer very complex solutions. (Here here , here and here ...)
It seems that in recent versions of the SDK, the Android can automatically process this backstack hierarchy without having to manually implement some kind of backstack using getChildFragmentManager, rather than getSupportFragmentManager in my transactions, where I replace fragments. However, I could not get this to work. (I intuitively feel that the right solution is to let Android handle this, as it feels that it manually overrides the back button, and implementing its own stack is a difficult hack.)
Can someone explain how to correctly implement the expected behavior when a separate stack is supported for each tab? Or perhaps a link to a simple, well-designed and modern example of how to achieve the desired behavior?
Additional information about my code: In my MainActivity.java, I create a 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; }