Hudson Worden
Hudson Worden

Reputation: 2353

Android: Trouble with FragmentStatePagerAdapter

I'm very new to Android development and I have been trying make an application that allows users to flip either to the left or right to change fragments. I'm using a FragmentStatePagerAdapter for this.

I first, in a for loop, created each fragment separately in the main activity's OnCreate() method and added them to the FragmentManager fManager.

for(Day day: days){
    ScreenSlidePageFragment fragment = new ScreenSlidePageFragment();
    this.fManager.beginTransaction().add(R.id.pager, fragment).commit();
}
fManager.executePendingTransactions();

I then set up UI elements and set the ViewPager's adapter like so

this.setUpUI();
mPager.setAdapter(mPagerAdapter);

The problem is is that I keep encountering this exception java.lang.IllegalStateException: Fragment Already Added...

I am very confused as to what is going on because the only place I add fragments to the FragmentManager is in the for-loop above. Do FragmentStatePagerAdapter's do something in the background that might cause this issue or am I not implementing my ScreenSlidePagerAdapter correctly?

Here is my code for the ScreenSlidePagerAdapter class:

private class ScreenSlidePagerAdapter extends FragmentStatePagerAdapter {
    public FragmentManager fm;
    public ScreenSlidePagerAdapter(FragmentManager fm) {
        super(fm);
        this.fm = fm;
    }
    @Override
    public Fragment getItem(int position) {
        Fragment f = fm.getFragments().get(position);
        return f;
    }
    @Override
    public int getCount() {
        return fm.getFragments().size();
    }
}

Input would be greatly appreciated.

Upvotes: 0

Views: 261

Answers (4)

Leonardo
Leonardo

Reputation: 3191

I usually do what you are trying like this:

public class FragmentSliderAdapter extends FragmentStatePagerAdapter {

    private List<Fragment> list = new ArrayList<Fragment>();

    public FragmentSliderAdapter(FragmentManager fm) {
        super(fm);

        list.add(new LoginFragment());
        list.add(new SignupFragment());
    }

    @Override
    public Fragment getItem(int arg0) {
        return list.get(arg0);
    }

    @Override
    public int getCount() {
        return list.size();
    }


}

Using list is cleaner and a good approach, since you can control what fragments are added to your adapter. On the activity that uses the adapter, I just do this:

viewPager = (ViewPager) findViewById(R.id.pager);
adapter = new FragmentSliderAdapter(getSupportFragmentManager());
viewPager.setAdapter(adapter);

And the activity xml I do:

<android.support.v4.view.ViewPager xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/pager"
    android:layout_width="match_parent"
    android:layout_height="match_parent" />

See if it helps !

Upvotes: 1

ILovemyPoncho
ILovemyPoncho

Reputation: 2792

You are getting the Fragment that is already in the FragmentManager and when you return it, the PagerAdapter tries to add it, but it is already there.

You don't have to add the fragments to the FragmentManager yourself. That's the FragmentStatePagerAdapter's job, that's why it receives a FragmentManager reference. You only have to create and return the fragments in getItem() and the PagerAdapter will add the fragments to the FragmentManager.

Upvotes: 1

Jorge Moreira
Jorge Moreira

Reputation: 95

I think the FragmentStatePagerAdapter already adds the fragments to your Activity (in the getItem() method). Try to remove that for loop.

Upvotes: 1

Abhishek Shukla
Abhishek Shukla

Reputation: 1242

You show create the fragments inside getItem(pos) method of Adapter. The adapter internally use the FragmentManager that you provide in constructor. Some what like this:

@Override
    public Fragment getItem(int position) {
        Fragment f = new ScreenSlidePageFragment();
        return f;
    }

Upvotes: 1

Related Questions