Assume I have 4 fragments A B C and D.
A and B are major fragments, C and D are minor.
I use navigation drawer to switch fragments.
A is the default starting fragment.
I want to achieve following features but cannot figure out how to play with the fragment manager and transactions.
- A -> B or B -> A, replace current fragment, do not push backstack, but I want to keep the current fragment status (e.g. list view position) after navigate back
- A/B -> C/D, add C/D on top of A/B, using back button to navigate back to A/B.
- C -> D or D -> C, replace current fagment
- C/D -> A/B, remove current fragment C/D and show A/B
Is the only way to implement this function that I should write some complicated function for switching the fragments (and also need to keep what is current fragment and what is the wanted target fragment)?
Is there better way out?
According to @DeeV 's answer, I came out with something like following.
LocalBrowse and WebsiteExplore are main fragments while Settings and About are sub fragments.
It seems to work fine but still a little bit ugly, any better idea?
private void switchToFragment(Class<?> targetFragmentClz) {
if(mCurrentFagment!=null && mCurrentFagment.getClass().equals(targetFragmentClz)) {
return;
}
BaseFragment targetFragment = null;
FragmentTransaction transaction = getSupportFragmentManager().beginTransaction();
if(targetFragmentClz.equals(LocalBrowseFragment.class)
|| targetFragmentClz.equals(WebsiteExploreFragment.class)) {
if(mCurrentFagment instanceof SettingsFragment //mCurrentFragment will not be null this time
|| mCurrentFagment instanceof AboutFragment) {
transaction.remove(mCurrentFagment);
}
if(mCurrentMainFagment==null || !mCurrentMainFagment.getClass().equals(targetFragmentClz)) {
targetFragment = (BaseFragment) Fragment.instantiate(this, targetFragmentClz.getName());
targetFragment.setHasOptionsMenu(true);
transaction.replace(R.id.ac_content_frame_main, targetFragment);
mCurrentMainFagment = targetFragment;
}
} else {
targetFragment = (BaseFragment) Fragment.instantiate(this, targetFragmentClz.getName());
targetFragment.setHasOptionsMenu(true);
getSupportFragmentManager().popBackStackImmediate();
transaction.replace(R.id.ac_content_frame_sub, targetFragment)
.addToBackStack(null);
}
transaction.commit();
mCurrentFagment = targetFragment;
}