15

I'm using a FragmentTabHost with multiple tabs (constructed as shown here). However, I cannot randomly address my tabs with getFragmentByTag (which returns in that case null) unless the addressed Tab has been activated by clicking on the tab at least once.

The FragmentTabHost seems to delay the creation of the tabs until we really need them (aka the user clicked on it and wants to view it).
Is there any way to force the Host to create them immediatelly such that I can safely access them by getFragmentByTag?
Or is it possible to create the Tabs "on my own" and just add them to the TabHost?

Dawodo
  • 433
  • 4
  • 15
  • If you initially call `onTabChanged(tabId)` for every tab (before switching to the current one), then that will force the `FragmentTabHost` to pre-populate all the fragments. You can do it yourself too, if you obtain the id of the fragment container. Alternatively, you can extend or fork it to implement your desired behavior. – corsair992 Apr 16 '15 at 02:03

1 Answers1

5

Is there any way to force the Host to create them immediately such that I can safely access them by getFragmentByTag?

No. because the transaction is executed at onAttachedToWindow(). lets have a look at the source code:

@Override
protected void onAttachedToWindow() {
    super.onAttachedToWindow();
    String currentTab = getCurrentTabTag();
    // Go through all tabs and make sure their fragments match.
    // the correct state.
    FragmentTransaction ft = null;
    for (int i=0; i<mTabs.size(); i++) {
        TabInfo tab = mTabs.get(i);
        tab.fragment = mFragmentManager.findFragmentByTag(tab.tag);
        if (tab.fragment != null && !tab.fragment.isDetached()) {
            if (tab.tag.equals(currentTab)) {
                // The fragment for this tab is already there and
                // active, and it is what we really want to have
                // as the current tab.  Nothing to do.
                mLastTab = tab;
            } else {
                // This fragment was restored in the active state,
                // but is not the current tab.  Deactivate it.
                if (ft == null) {
                    ft = mFragmentManager.beginTransaction();
                }
                ft.detach(tab.fragment);
            }

        }
    }
    // We are now ready to go.  Make sure we are switched to the
    // correct tab.
    mAttached = true;
    ft = doTabChanged(currentTab, ft);
    if (ft != null) {
        ft.commit();
        mFragmentManager.executePendingTransactions();
    }
}
@Override
protected void  onDetachedFromWindow() {
    super.onDetachedFromWindow();
    mAttached = false;
}

As you see the mFragmentManager.executePendingTransactions(); is executed at onAttachedToWindow.

Or is it possible to create the Tabs "on my own" and just add them to the TabHost?

yes, you can use tabhost and you can create tab content with below methods.

public TabHost.TabSpec setContent (int viewId)

public TabHost.TabSpec setContent (Intent intent)

public TabHost.TabSpec setContent (TabHost.TabContentFactory contentFactory)

mmlooloo
  • 18,937
  • 5
  • 45
  • 64
  • 1
    Also helpful for me was reviewing the source code in the `DoTabChanged` method in `FragmentTabHost.java`. Thanks for linking to the source code. – Nate Cook Apr 16 '15 at 15:27