The Problem
Before I describe my current setup I will describe my problem. I need to have hierarchal navigation between fragments inside separate tabs. Say I drill down on level in a tab, I then switch tabs and then go back to the first, original tab, I need it to be on the drilled down level and then have the ability to go back up to the top level of that tab.
Now onto my setup.
I have an application with one activity called MainActivity. This activity is what controls my tabbed action bar. I have followed many different tutorials to handle the switching of Fragments when a tab is selected and here is the code below that works drawing your attention to the onTabSelected and onTabUnselected methods.
MainActivity — Tab Listener
public static class MyTabListener<T extends Fragment> implements ActionBar.TabListener {
private final Activity mActivity;
private final String mTag;
private final Class<T> mClass;
private final Bundle mArgs;
private Fragment mFragment;
public MyTabListener(Activity activity, String tag, Class<T> clz) {
this(activity, tag, clz, null);
}
public MyTabListener(Activity activity, String tag, Class<T> clz, Bundle args) {
mActivity = activity;
mTag = tag;
mClass = clz;
mArgs = args;
// Check to see if we already have a fragment for this tab, probably
// from a previously saved state. If so, deactivate it, because our
// initial state is that a tab isn't shown.
mFragment = mActivity.getFragmentManager().findFragmentByTag(mTag);
if (mFragment != null && !mFragment.isDetached()) {
FragmentTransaction ft = mActivity.getFragmentManager().beginTransaction();
ft.detach(mFragment);
ft.commit();
}
}
public void onTabSelected(Tab tab, FragmentTransaction ft) {
Log.e("FRAGMENT","Selected Fragment With Tag " + mTag);
if (mFragment == null) {
mFragment = Fragment.instantiate(mActivity, mClass.getName(), mArgs);
ft.add(android.R.id.content, mFragment, mTag);
} else {
ft.attach(mFragment);
}
}
public void onTabUnselected(Tab tab, FragmentTransaction ft) {
if (mFragment != null) {
ft.detach(mFragment);
}
}
public void onTabReselected(Tab tab, FragmentTransaction ft) {
Toast.makeText(mActivity, "Reselected!", Toast.LENGTH_SHORT).show();
}
}
When I am on Tab1 viewing Fragment1', when a button is pressed I then show anotherFragmentcalledFragment2` which I need the ability to go back from. The code below works if I just stay on that tab however when navigating away from the tab and back to it, everything messes up.
MainActivity — Showing second fragment
Fragment tdFrag = Fragment.instantiate(this, SecondFragment.class.getName());
FragmentTransaction ft = getFragmentManager().beginTransaction();
ft.replace(android.R.id.content, tdFrag, "secondfrag");
ft.addToBackStack(null);
ft.commit();
My Thoughts
I think it must be the way I detach the fragments and handle the switching over when a new tab is pressed. Maybe I need to implement some way of storing each individual backstack for each tab and loading the fragments from that instead of the system back stack?
Any help would be great. I have tried to explain it as thoroughly and simply as possible.
Thanks in advance.
Ok so after a bit of experimentation I decided to implement a custom backstack using enumerated types.
I have two types of enumerated types: a
ViewTypeandCurrentTabtype. TheCurrentTabtype tells me what tab I’m currently viewing and theViewTypetells me what view is being viewed in these tabs. I have an instance of aViewTypefor each tab I have to store where I am in the hieerarchy.To implement a backstack I override the method thats called when the back button is pressed.
So in where it checks for the back button I put my code to check the current tab and the separate view types. That way I know where I am and if I push back I know where I need to go.
I hope this helps any questions just post a comment.