FragmentTabHost - Tabs not addressable until viewed for the first time
Asked Answered
F

1

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?

Floeter answered 11/8, 2013 at 7:39 Comment(1)
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.Aureolin
H
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)

Henbane answered 16/4, 2015 at 12:17 Comment(1)
Also helpful for me was reviewing the source code in the DoTabChanged method in FragmentTabHost.java. Thanks for linking to the source code.Reconnoitre

© 2022 - 2024 — McMap. All rights reserved.