Search code examples
javaandroidandroid-fragmentsandroid-tabhost

Adding tabs to a nested FragmentTabHost with dynamically created fragments


I'm trying to create a FragmentTabHost nested in a fragment. The concept is working except one thing which is driving me crazy. In the .addTab() method I give a dynamically created fragment.getClass as the 2nd argument like this:

mTabHost.addTab(
            mTabHost.newTabSpec("Tab1").setIndicator(adapterlist[0], null),
            SiteDetailsFragment.newInstance(test1).getClass(), null);

In the .newInstance() method, the test1 argument is an ArrayList, and the fragment dynamically creating a Tablelayout with TextViews and EditTexts in each row with the data that the list contains. The adapterlist[] is a simple string array.

This is working fine.

The problem is: I want to create more tabs from different SiteDetailsFragment instances like this:

      for (int i=0;i<=currentDetailsList.size()-1;i++) {

      mTabHost.addTab(mTabHost.newTabSpec("tab" + i)
      .setIndicator(adapterlist[i], null),
      SiteDetailsFragment.newInstance(currentDetailsList
      .get(i)).getClass(),null);

      }

The currentDetailsList is a list of list, the difference between the instances is the given list in the .newInstance() method. This cycle will create the exact number of tabs defined by the currentDetailsList but the content of all tabs is the instance created by the last list item, and i have no idea why. I tried many things, but perhaps I'm missing something. If anyone have suggestions, I would like to read it.

Thanks!


Solution

  • The issue is likely happening because you're creating a new instance of SiteDetailsFragment but essentially throwing it away. My guess is that your SiteDetailsFragment.newInstance() is storing static data, which it should not. What you want to do is put your ArrayList into a Bundle and provide that and the class name to .addTab(). For example:

    Bundle args = new Bundle();
    args.putStringArrayList(ARG_NAME, test1);
    mTabHost.addTab(mTabHost.newTabSpec("Tab1").setIndicator(adapterlist[0], null),
        SiteDetailsFragment.class,
        args);
    

    This is assuming that your test1 list is just a list of String objects. If it is something else which is supported by Parcel then you'll need to use the correct Bundle method to add it.

    The addTab() method uses Fragment.instantiate() method to create a new Fragment object of the class (name) you provided as well as set the provided Bundle as the arguments; the same as a typical newInstance() method you would manually create.