IllegalStateException when using FragmentPagerAdapter with ArrayAdapter

advertisements

I am building an app with 3 tabs on the root view. I want to include swipe to change tab function so I am using the support framework and the FragmentPagerAdapter as suggested in Android training documentation. My first two tabs were built without a problem using custom adapters. However when I added a third tab using ArrayAdapter, changing between tabs more than twice generates IllegalStateException.

04-17 17:17:13.792: E/AndroidRuntime(2158): FATAL EXCEPTION: main
04-17 17:17:13.792: E/AndroidRuntime(2158): java.lang.IllegalStateException: The specified child already has a parent. You must call removeView() on the child's parent first.
04-17 17:17:13.792: E/AndroidRuntime(2158):     at android.view.ViewGroup.addViewInner(ViewGroup.java:3509)
04-17 17:17:13.792: E/AndroidRuntime(2158):     at android.view.ViewGroup.addView(ViewGroup.java:3380)
04-17 17:17:13.792: E/AndroidRuntime(2158):     at android.view.ViewGroup.addView(ViewGroup.java:3325)
04-17 17:17:13.792: E/AndroidRuntime(2158):     at android.view.ViewGroup.addView(ViewGroup.java:3301)
04-17 17:17:13.792: E/AndroidRuntime(2158):     at android.support.v4.app.NoSaveStateFrameLayout.wrap(NoSaveStateFrameLayout.java:40)
04-17 17:17:13.792: E/AndroidRuntime(2158):     at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:931)
04-17 17:17:13.792: E/AndroidRuntime(2158):     at android.support.v4.app.FragmentManagerImpl.attachFragment(FragmentManager.java:1280)
04-17 17:17:13.792: E/AndroidRuntime(2158):     at android.support.v4.app.BackStackRecord.run(BackStackRecord.java:672)
04-17 17:17:13.792: E/AndroidRuntime(2158):     at android.support.v4.app.FragmentManagerImpl.execPendingActions(FragmentManager.java:1467)
04-17 17:17:13.792: E/AndroidRuntime(2158):     at android.support.v4.app.FragmentManagerImpl.executePendingTransactions(FragmentManager.java:472)
04-17 17:17:13.792: E/AndroidRuntime(2158):     at android.support.v4.app.FragmentPagerAdapter.finishUpdate(FragmentPagerAdapter.java:141)
04-17 17:17:13.792: E/AndroidRuntime(2158):     at android.support.v4.view.ViewPager.populate(ViewPager.java:1068)
04-17 17:17:13.792: E/AndroidRuntime(2158):     at android.support.v4.view.ViewPager.populate(ViewPager.java:914)
04-17 17:17:13.792: E/AndroidRuntime(2158):     at android.support.v4.view.ViewPager$3.run(ViewPager.java:244)
04-17 17:17:13.792: E/AndroidRuntime(2158):     at android.view.Choreographer$CallbackRecord.run(Choreographer.java:749)
04-17 17:17:13.792: E/AndroidRuntime(2158):     at android.view.Choreographer.doCallbacks(Choreographer.java:562)
04-17 17:17:13.792: E/AndroidRuntime(2158):     at android.view.Choreographer.doFrame(Choreographer.java:531)
04-17 17:17:13.792: E/AndroidRuntime(2158):     at android.view.Choreographer$FrameDisplayEventReceiver.run(Choreographer.java:735)
04-17 17:17:13.792: E/AndroidRuntime(2158):     at android.os.Handler.handleCallback(Handler.java:730)
04-17 17:17:13.792: E/AndroidRuntime(2158):     at android.os.Handler.dispatchMessage(Handler.java:92)
04-17 17:17:13.792: E/AndroidRuntime(2158):     at android.os.Looper.loop(Looper.java:137)
04-17 17:17:13.792: E/AndroidRuntime(2158):     at android.app.ActivityThread.main(ActivityThread.java:5103)
04-17 17:17:13.792: E/AndroidRuntime(2158):     at java.lang.reflect.Method.invokeNative(Native Method)
04-17 17:17:13.792: E/AndroidRuntime(2158):     at java.lang.reflect.Method.invoke(Method.java:525)
04-17 17:17:13.792: E/AndroidRuntime(2158):     at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:737)
04-17 17:17:13.792: E/AndroidRuntime(2158):     at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:553)
04-17 17:17:13.792: E/AndroidRuntime(2158):     at dalvik.system.NativeStart.main(Native Method)

As you can see it's none of my code, just Android library code. Anybody has any idea on how to fix it? I've been trying out everything I found on this forum but nothing worked for me yet.

public class PreciousTrackerPagerAdapter extends FragmentPagerAdapter {

public static final int TAB_COUNT = 3;
public static final int TAB_PRECIOUS_MOVES = 0;
public static final int TAB_PRECIOUS_ITEMS = 1;
public static final int TAB_PRECIOUS_CATEGORY = 2;

private PreciousMovesFragment movesFragment;
private PreciousItemsFragment itemsFragment;
private PreciousCategoryFragment categoryFragment;

public PreciousTrackerPagerAdapter(FragmentManager fm) {
    super(fm);
}

@Override
public Fragment getItem(int index) {
    switch (index) {
    case TAB_PRECIOUS_MOVES:
        if (movesFragment == null) {
            movesFragment = new PreciousMovesFragment();
        }
        return movesFragment;
    case TAB_PRECIOUS_ITEMS:
        if (itemsFragment == null) {
            itemsFragment = new PreciousItemsFragment();
        }
        return itemsFragment;
    case TAB_PRECIOUS_CATEGORY:
        if (categoryFragment == null) {
            categoryFragment = new PreciousCategoryFragment();
        }
        return categoryFragment;
    default:
        return null;
    }
}

@Override
public int getCount() {
    return TAB_COUNT;
}

}

The fragment that I added to the third tab that seemed to cause the problem here.

public class PreciousCategoryFragment extends Fragment {

private List<PreciousCategory> categoryList;
private View rootView;

public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
    super.onCreateView(inflater, container, savedInstanceState);

    if (rootView == null) {
        rootView = inflater.inflate(R.layout.category_list, null);
    }

    return rootView;
}

@Override
public void onViewCreated(View view, Bundle savedInstanceState) {
    super.onViewCreated(view, savedInstanceState);

    refreshList();
}

private void refreshList() {
    PreciousTrackerModel model = PreciousTrackerModel.getInstance(getActivity());
    categoryList = model.getCategoryList();
    ArrayAdapter<PreciousCategory> adapter = new ArrayAdapter<PreciousCategory>(getActivity(), android.R.layout.simple_list_item_1, categoryList);
    ListView listView = (ListView) getActivity().findViewById(R.id.lstCategory);
    listView.setAdapter(adapter);
}

}

And how I added the tabs in the main activity. Each tab takes the entire content space.

    @Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);

    setContentView(R.layout.activity_main);
    model = PreciousTrackerModel.getInstance(this);

    pagerAdapter = new PreciousTrackerPagerAdapter(getSupportFragmentManager());
    viewPager = (ViewPager) findViewById(R.id.pager);
    viewPager.setAdapter(pagerAdapter);
    viewPager.setOnPageChangeListener(new ViewPager.SimpleOnPageChangeListener() {
        public void onPageSelected(int position) {
            // When swiping between pages, select the
            // corresponding tab.
            getActionBar().setSelectedNavigationItem(position);
        }
    });

    // enable tabs in action bar
    final ActionBar actionBar = getActionBar();
    actionBar.setNavigationMode(ActionBar.NAVIGATION_MODE_TABS);

    // add tabs with listener
    actionBar.addTab(actionBar.newTab().setText(R.string.moves).setTabListener(this));
    actionBar.addTab(actionBar.newTab().setText(R.string.items).setTabListener(this));
    actionBar.addTab(actionBar.newTab().setText(R.string.category).setTabListener(this));
}


I think that PreciousCategoryFragment::onCreateView is your problem.

It should look like this:

@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
    return inflater.inflate(R.layout.fragment_messages, null, false);
}