2012-08-01 41 views
31

我想了解此异常以实现适当的修复。java.lang.IllegalStateException:关键字f1的片段不再存在:索引3

概述:

有一个ViewPager,它采用了FragmentStatePagerAdapter通过的getItem和MyFragmentClass.newInstance(...)实例2个片段。

适配器的的getItem看起来是这样的:

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

问题:

当活动被破坏,并产生再次,适配器再次intantiated,与MyFragmentClass.newInstance(...)再次创造了碎片......但随后在这条线:

pager.setAdapter(adapter);

我得到的提到例外。

我在源看在异常被抛出,那就是:

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

所以,一个包被传递那里,它引用我的旧片段一些状态,但是这并不对应当前状态(mActive),并且抛出了exceptio。

我不明白这背后的想法是什么,或者我实际上应该实例化片段的方式......所以我不知道如何解决。

我也尝试了一些技巧,我从其他一些方面有:

pager.setOffscreenPageLimit(1);

为了避免该片段时,他们关闭屏幕(摧毁了2页的情况下viewpager,虽然唐不知道它是否适用于状态适配器)。但似乎没有关系,至少,它没有帮助,仍然得到相同的例外。

我现在所做的是在线上放一个try catch块,然后,我得到空白页而不是一个碰撞盒,也不好。

+0

您是否找到适合您问题的解决方案? – savepopulation 2014-11-26 18:27:14

+0

您是否曾经找到过解决方案 – 2015-07-17 10:46:16

+0

我不记得了,对不起:( – Ixx 2015-07-17 10:58:31

回答

18

如果您不希望碎片在离屏时被回收,则应该使用FragmentPagerAdapter而不是FragmentStatePagerAdapter

+0

在这种情况下有什么区别? – 2014-01-28 09:26:03

+2

'FragmentPagerAdapter'在访问内存时加载内存中的每个片段'FragmentStatePagerAdapter'一旦超过offscreenPageLimit参数就释放它对片段的引用 – tad 2014-01-28 10:22:27

+0

所以如果我们设置了offscreenpagelimit它不会再有问题了(对于'FragmentStatePagerAdapter') – 2014-01-28 10:25:40

33

这可以帮助 -

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

添加行上面FragmentStatePagerAdapter

+1

谢谢attels它像一个魅力工作 – CodingRat 2015-07-30 09:35:11

+2

这适用于处理后堆栈中的分页适配器。谢谢! – 2015-08-10 20:22:55

+1

它适合我! – GeekHades 2015-12-25 00:52:59

3

我在这个问题上奋斗了整整一天,但现在我找到了解决方案。

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

setOffscreenPageLimit一套应保留在视图层次结构的当前页面的两侧处于空闲状态的页数。超出此限制的页面将在需要时从适配器重新创建。

+0

这使用了大量的内存......节省了不保存状态和所有的麻烦..但是从长远来看,当存在大量数据时 – Kushan 2017-02-01 21:22:55

1

非常好!由于是重复pager.setAdapter(adapter);当呼叫restoreState原因的异常:

Fragment no longer exists for key f0: index 0 

,我们可以释放片段RootView

public void onDestroyView() { 
    super.onDestroyView(); 
    if (isRecyclerRootViewAlways()) { 
     mRootView = null;//<-- 
    } 
    mMyFragmentLifecycle.onFragmentDestroyView(this); 
} 
0

使用

getFragmentManager()

在片段适配器 不儿童片段管理器

PagerAdapter adapter = new PagerAdapter(getFragmentManager()); 

我希望这有助于。

相关问题