0

I am using a FragmentTabHost for simple two tab setting. However tabs get recreated when I switch from one to another. How to avoid this. Although I tried to hide/show, that didnt work see updateTab method below.

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
        Bundle savedInstanceState) 
   {

    mTabHost = new FragmentTabHost(getActivity());
    mTabHost.setup(getActivity(), getChildFragmentManager(), R.id.tabhost);

    mTabHost.addTab(
            mTabHost.newTabSpec("tabAchievements").setIndicator(
                    getResources().getString(R.string.tab_achievements),
                    getResources().getDrawable(R.drawable.location)),
            CompleteFragment.class, null);
    mTabHost.addTab(
            mTabHost.newTabSpec("tabIncomplete").setIndicator(
                    getResources().getString(R.string.tab_incomplete),
                    getResources().getDrawable(R.drawable.eye)),
            IncompleteFragment.class, null);

    myLastTag = "tabAchievements";
    mTabHost.setOnTabChangedListener(new OnTabChangeListener() {

        public void onTabChanged(String tabId) {
            if (tabId.equals("tabAchievements")) {

                updateTab(tabId, R.string.tab_achievements);
                return;
            }
            if (tabId.equals("tabIncomplete")) {
                updateTab(tabId, R.string.tab_incomplete);
                return;
            }
        }
    });
    return mTabHost;
}

private void updateTab(String tabId, int placeholder) {
    Fragment newTab = getChildFragmentManager().findFragmentByTag(tabId);
    Fragment mLastTab = getChildFragmentManager().findFragmentByTag(
            myLastTag);
    myLastTag = tabId;
    if (mLastTab != newTab) {
        FragmentTransaction ft = activity.getSupportFragmentManager()
                .beginTransaction();
        if (mLastTab != null) {
            if (mLastTab != null) {
                ft.hide(mLastTab);
            }
        }
        if (newTab == null) {
            if (tabId == "tabAchievements")
                newTab = Fragment.instantiate(activity,
                        CompleteFragment.class.getName(), null);
            else
                newTab = Fragment.instantiate(activity,
                        IncompleteFragment.class.getName(), null);
            ft.add(android.R.id.tabcontent, newTab, null);

        } else {
            ft.show(newTab);
        }
        ft.commit();
    }
}
pats
  • 1,273
  • 2
  • 20
  • 43

1 Answers1

3

I had the same issue, and finally got it solved. It's not enough to override OnTabChangeListener as the FragmentTabHost internally does first an attach or dettach of the fragments before calling your listener, so the lifecycle from OnCreateView is still called. Look at this solution, How to maintain fragment's state in the application, it worked for me. Download the last FragmentTabHost.java code and replace the doTabChanged with (I've also added the call to onPause before hide and onResume after show, otherwise they don't get called):

private FragmentTransaction doTabChanged(String tabId, FragmentTransaction ft) {
    TabInfo newTab = null;
    for (int i=0; i<mTabs.size(); i++) {
        TabInfo tab = mTabs.get(i);
        if (tab.tag.equals(tabId)) {
            newTab = tab;
        }
    }
    if (newTab == null) {
        throw new IllegalStateException("No tab known for tag " + tabId);
    }
    if (mLastTab != newTab) {
        if (ft == null) {
            ft = mFragmentManager.beginTransaction();
        }
        if (mLastTab != null) {
            if (mLastTab.fragment != null) {
                mLastTab.fragment.onPause();
                ft.hide(mLastTab.fragment);
            }
        }
        if (newTab != null) {
            if (newTab.fragment == null) {
                newTab.fragment = Fragment.instantiate(mContext,
                        newTab.clss.getName(), newTab.args);
                ft.add(mContainerId, newTab.fragment, newTab.tag);
                findViewById(mContainerId).setContentDescription("DEBUG. add fragment to this container");
            } else {
                if (newTab.fragment.isHidden()){
                    ft.show(newTab.fragment);
                    newTab.fragment.onResume();
                }
                else{
                    ft.attach(newTab.fragment);
                }
            }
        }

        //mPreviousTab = mLastTab;
        mLastTab = newTab;
    }
    return ft;

}

and don't override OnTabChangedListener. You have of course to change the references to android.support.v4.app.FragmentTabHost with your package path, and do it also in your Layout file...

Community
  • 1
  • 1
Luchi Valles
  • 181
  • 4