I found a ton of these messages in StackOverflow. Like those many other people, I have the same problem with tab contents overlapping when switching tabs. None of the advises I found didn't work with my problem.
When my app launches, it correctly shows the contents of the first tab. When I click the other tab, the old contents stay on the screen and the other tab's content is added on the screen, too. When switching tabs second time, all the contents disappear. Switching tabs won't do anyhting anymore.
I followed Google's Developer document here.
My application has this onCreate
method.. The class extends ActionBarActivity
from the support libary android.support.v7.app
.
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
ActionBar actionBar = getSupportActionBar();
actionBar.setNavigationMode(ActionBar.NAVIGATION_MODE_TABS);
actionBar.setDisplayShowTitleEnabled(false);
Tab tab = actionBar.newTab().setText("TAB1").setTabListener(new TabListener<Tab1Class>(this, "tab1", Tab1Class.class));
actionBar.addTab(tab);
tab = actionBar.newTab().setText("TAB2").setTabListener(new TabListener<Tab2Class>(this, "tab2", Tab2Class.class));
actionBar.addTab(tab);
}
My TabListener
class is copied from the page I linked:
public class TabListener<T extends Fragment> implements ActionBar.TabListener {
private Fragment mFragment;
private final Activity mActivity;
private final String mTag;
private final Class<T> mClass;
public TabListener(Activity activity, String tag, Class<T> clz) {
mActivity = activity;
mTag = tag;
mClass = clz;
}
@Override
public void onTabSelected(Tab tab, FragmentTransaction ft) {
if(mFragment == null) {
mFragment = Fragment.instantiate(mActivity, mClass.getName());
ft.add(android.R.id.content, mFragment, mTag);
} else {
ft.attach(mFragment);
}
}
@Override
public void onTabUnselected(Tab tab, FragmentTransaction ft) {
if(mFragment != null) {
ft.detach(mFragment);
}
}
@Override
public void onTabReselected(Tab tab, FragmentTransaction ft) {}
}
Both classes I use as the contents of the tabs extend Fragment from android.support.v4.app.Fragment
. They inflate their layouts in onCreateView
methods.
What's wrong?
After a quick look through the code for the
ActionBarActivity
, there seems to be a bug for theICS
and above part of the implementation of theActionBar
(the code should work for preICS
devices) which also takes care of the tabs.In the
ActionBarImplICS
class which represents the implementation forICS
devices it seems theFragmentTransaction
passed to theonTabUnselected()
callback is completely useless as it isn't committed anywhere after the listener's callback returns(the transaction is committed for the other two callbacks of theTabListener
). So a committed fragment will never be detached from the layout on a tab selection and it will stay getting the overlapping content(due to theFrameLayout
which holds both fragments).I've written another implementation of the
TabListener
interface which does all of its job from only one of the callbacks which isn't affected by the above bug(onTabSelected()
):Which you could then use as:
I would advise you to set a container as the content view(and also for the tab content) and not use the
android.R.id.content
container. Keep in mind that my implementation doesn't take care of configuration changes.