0

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.

2
  • share your main activity where you are replacing fragments... Commented Oct 17, 2014 at 7:38
  • Hi rohit thank you for your help. I have now updated the main post. Commented Oct 17, 2014 at 7:43

2 Answers 2

1

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();
    }
}
Sign up to request clarification or add additional context in comments.

5 Comments

Hi Narendra, thank you for your post. Could you please help me - What if I would like to add a fragment in real time instead of only in the begining?
And is it recommended to use FragmentPagerAdapter instead of FragmentStatePagerAdapter?
Hi Narendra, do you know how to add a fragment during runtime?
Thank you nahrendra! it seems to be working. I added the following function in MyPagerAdapter: public void addFrag(Ad ad) { AdFragment f = new AdFragment(ad); frags.add(f); this.notifyDataSetChanged(); }
use this line on OnTabChanged() mViewPager.setCurrentItem(pos);
1

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);
    }

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.