code
code

Reputation: 5642

Trouble with IllegalStateException using ViewPager and FragmentStatePagerAdapter

I am having an issue while using a ViewPager with a FragmentStatePagerAdapter. Basically, during run time, I'd like to add new fragments to the ViewPager as time goes on. For some reason, the first fragment is added successfully, however the second fragment causes an "IllegalStateException".

       public class AdActivity extends FragmentActivity implements IChannelListener 
{
   private static final String TAG = "AdActivity";
   public static int NUM_PAGES = 0;
   private VerticalViewPager mPager;
   private PagerAdapter mPagerAdapter;

   public Channel getChannel() {
      return channel;
   }

   @Override
   protected void onCreate(Bundle savedInstanceState) {
      super.onCreate(savedInstanceState);
      AdController.getInstance().setAdActivity(this);
      Log.d(TAG, "onCreate()");
      setContentView(R.layout.activity_ad);

      // Instantiate a ViewPager and a PagerAdapter.
      mPager = (VerticalViewPager) findViewById(R.id.pager);
      mPagerAdapter = new AdPagerAdapter(getFragmentManager());
      mPager.setAdapter(mPagerAdapter);
      mPager.setOnPageChangeListener(new ViewPager.SimpleOnPageChangeListener() {
          @Override
          public void onPageSelected(int position) {
              invalidateOptionsMenu();
          }
      });

      // To stop destroying unused fragments
      mPager.setOffscreenPageLimit(15);

      Log.d(TAG, "endOfOnCreate()");
   }

   public void insertAdFragment(final Ad ad)   {
       Log.d(TAG, "insertAdFragment()");
       runOnUiThread(new Runnable(){
            @Override
            public void run() 
            {
                AdFragment fragment = new AdFragment(ad);
                AdFragment.fragments.add(0, fragment);
                NUM_PAGES = NUM_PAGES + 1;
                mPagerAdapter.notifyDataSetChanged();
            }
       });

       Log.d(TAG, "end insertAdFragment()");
   }

   /*
    * Pager Adapter that represents the objects in sequence.
    * */
   private class AdPagerAdapter extends FragmentStatePagerAdapter 
   {
    private static final String TAG = "AdPagerAdapter";

       public AdPagerAdapter(FragmentManager fragmentManager) 
       {
           super(fragmentManager);
           Log.d(TAG, "AdPagerAdapter()");
       }

    @Override
       public Fragment getItem(int position) 
       {
        Log.d(TAG, "getItem(" + position + ") : size of fragments is... " + AdFragment.fragments.size());
           //return AdFragment.create(position);
        return AdFragment.fragments.get(position);
       }

       @Override
       public int getCount() {
           Log.d(TAG, "getCount() : " + NUM_PAGES);
           return NUM_PAGES;
       }
   }
}

The function above insertAdFragment is called once per minute. Prior to reaching the function, NUM_PAGES has a value of 0. A Fragment is added to the beginning of a "fragments" list. Then, notifyDataSetChanged() is called. Below is the AdPagerAdapter:

private class AdPagerAdapter extends FragmentStatePagerAdapter 
   {
    private static final String TAG = "AdPagerAdapter";

       public AdPagerAdapter(FragmentManager fragmentManager) 
       {
           super(fragmentManager);
           Log.d(TAG, "AdPagerAdapter()");
       }

    @Override
       public Fragment getItem(int position) 
       {
        Log.d(TAG, "getItem(" + position + ") : size of fragments is... " + AdFragment.fragments.size());

        return AdFragment.fragments.get(position);
       }

       @Override
       public int getCount() {
           Log.d(TAG, "getCount() : " + NUM_PAGES);
           return NUM_PAGES;
       }
   }

When a second fragment is added, the App crashes :( Ugh I can't for the life of me figure this out.

Upvotes: 0

Views: 303

Answers (2)

Narendra Kumar
Narendra Kumar

Reputation: 581

Just implement onpagechangelistener and override this methods

@Override
    public void onPageScrollStateChanged(int arg0) 
    {
    }
    @Override
    public void onPageScrolled(int arg0, float arg1, int arg2) 
    {
    }
    @Override
    public void onPageSelected(int arg0) {
        mTabHost.setCurrentTab(arg0);
    }

Upvotes: 1

Narendra Kumar
Narendra Kumar

Reputation: 581

Add your Fragment class to List in mainactivity as below,

private void ViewPagerInitialize()
     {
         List<Fragment> fragments = new Vector<Fragment>();
            fragments.add(Fragment.instantiate(this, AndroidFragment.class.getName()));
            fragments.add(Fragment.instantiate(this, AppleFragment.class.getName()));
            fragments.add(Fragment.instantiate(this, MicrosoftFragment.class.getName()));
            mPageradapter  = new MyPagerAdapter(super.getSupportFragmentManager(), fragments);
            mViewPager = (ViewPager)super.findViewById(R.id.pager);
            mViewPager.setAdapter(mPageradapter);
            mViewPager.setOnPageChangeListener(this);
     }

And use this view pager adapter class

public class MyPagerAdapter extends FragmentPagerAdapter
{
    private List<Fragment> fragments;
    public MyPagerAdapter(FragmentManager mFManager,List<Fragment> fragments) {
        super(mFManager);
        this.fragments = fragments;
    }
    @Override
    public Fragment getItem(int arg0) {

        return fragments.get(arg0);
    }

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

Upvotes: 1

Related Questions