问题描述:

I want to understand this exception in order to implement a proper fix.

Overview:

There's a ViewPager and it uses a FragmentStatePagerAdapter to instantiate 2 fragments via getItem and MyFragmentClass.newInstance(...).

Adapter's getItem looks like this:

@Override

public Fragment getItem(int position) {

Fragment fragment = null;

switch(position) {

case 0:

fragment = MyFragment2.newInstance(par1);

break;

case 1:

fragment = MyFragment2.newInstance(par2, par3);

break;

}

return fragment;

}

Problem:

When the activity is destroyed, and created again, the adapter is intantiated again, the fragments created again with MyFragmentClass.newInstance(...)... but then on this line:

pager.setAdapter(adapter);

I get the mentioned exception.

I looked in the source where the exception is thrown, it's this:

@Override

public Fragment getFragment(Bundle bundle, String key) {

int index = bundle.getInt(key, -1);

if (index == -1) {

return null;

}

if (index >= mActive.size()) {

throw new IllegalStateException("Fragement no longer exists for key "

+ key + ": index " + index);

}

Fragment f = mActive.get(index);

if (f == null) {

throw new IllegalStateException("Fragement no longer exists for key "

+ key + ": index " + index);

}

return f;

}

So, a bundle is passed there, with some state which references my old fragments, but this doesn't correspond to the current state (mActive), and the exceptio is thrown.

I don't understand what's the idea behind this, or which way I'm actually supposed to instantiate the fragments... so I have no idea how to solve.

I also tried some trick I got from some other context:

pager.setOffscreenPageLimit(1);

In order to avoid that the fragments are destroyed when they are off screen (in the case of 2 pages viewpager, although don't know if it works well with state adapter). But don't seems to be related, at least, it doesn't help, still get the same exception.

What I did right now is put a try catch block around the line, and well, then I get blank pages instead of a crash box, also not good.

网友答案:

This could help -

@Override
public Parcelable saveState() {
    return null;
}

Add the line above in FragmentStatePagerAdapter.

网友答案:

If you don't want the fragments to get reclaimed when they are offscreen, you should be using FragmentPagerAdapter and not FragmentStatePagerAdapter.

网友答案:

I have struggle on this problem for whole day, but now I found the solution.

private ViewPager _mViewPager;
_mViewPager.setOffscreenPageLimit(5);
//5 is how much page you have.

setOffscreenPageLimit Set the number of pages that should be retained to either side of the current page in the view hierarchy in an idle state. Pages beyond this limit will be recreated from the adapter when needed.

相关阅读:
Top