FragmentStatePagerAdapter IllegalStateException:<myfragment>当前不在FragmentManager中</myfragment>

时间:2012-07-02 15:12:31

标签: android fragment

我在一些使用FragmentStatePagerAdapter的活动的onResume()中获得了这个。使用设备的后退按钮时。不总是。不可重复。

我正在使用支持包v4,最新修订版(8)。

已经在谷歌搜索过,没有成功找到有用的答案。

查看源代码,它会抛出:FragmentManager.java

@Override
public void putFragment(Bundle bundle, String key, Fragment fragment) {
    if (fragment.mIndex < 0) {
        throw new IllegalStateException("Fragment " + fragment
                + " is not currently in the FragmentManager");
    }
    bundle.putInt(key, fragment.mIndex);
}

但为什么片段的索引&lt; 0那里?

实例化片段的代码:

@Override
public Fragment getItem(int position) {
    Fragment fragment = null;

    switch(position) {
        case 0:
            fragment = MyFragment.newInstance(param1);
            break;
        case 1:
            fragment = MyFragment2.newInstance(param2, param3);
            break;
    }
    return fragment;
}

@Override
public int getCount() {
    return 2;
}

7 个答案:

答案 0 :(得分:15)

如果您的ViewPager布置在片段(不是激活)内:

mViewPager.setAdapter(new MyFragmentStatePagerAdapter(get Child FragmentManager()));

答案 1 :(得分:10)

我在这里遇到了同样的错误,但出于其他原因。

在我的情况下,我在FragmentStatePagerAdapter中覆盖了getItemPosition。我的意思是如果项目存在则返回位置,或者如果它不存在则返回POSITION_NONE。

嗯,我的问题是,当我的收藏品变空时,我返回了POSITION_NONE。这打破了一切。

我的修复是当我有一个空集合时返回POSITION_UNCHANGED。

希望它可以帮助别人。

答案 2 :(得分:8)

理解错误的两个关键事项是:

  1. 有时发生
  2. 它发生在onResume()
  3. 根据这些信息,ViewPager可能不会保留Fragment的状态。如果您直接从Fragment操纵Activity,可能会出现页外Fragment被破坏而您的Activity正试图操纵null片段。要保留Fragment的状态,即使它不在当前屏幕中,修复也很简单:

    private static final int NUM_ITEMS = 2;
    
    ViewPager mPager = /** instantiate viewpager **/;
    mPager.setOffscreenPageLimit(NUM_ITEMS-1);
    

    你可以在这里阅读:

    ViewPager Fragments getting destroyed over time?

答案 3 :(得分:5)

知道了,原因是,我每次都在onResume()中对适配器进行实例化。

如果我只在实例的生命周期中实例化一次适配器,则不会再发生这种情况。

答案 4 :(得分:4)

此异常表示您尝试将片段附加到不再是正确状态的活动以附加片段。这意味着,每当我们尝试附加片段(,特别是通过异步调用)时,有人按下后退按钮的可能性很小,并且当您附加时,活动正在合并中被摧毁片段。这并不总是可重复的,因为它只是一种竞争条件,并且可能并不总是发生..

有两种方法可以解决这个问题:

1)当您调用活动的onSaveInstanceState并发布到您尝试附加片段时,会发生这种情况,因为android现在无法保存片段的状态,它会抛出异常。要解决此问题,如果您没有保存片段的状态,请尝试使用

提交事务时

commitAllowingStateLoss()

2)为了非常安全,在附加片段之前检查您的活动是否处于正确状态,请在onPause中使用以下代码:

    boolean isInCorrectState;

    public void onCreate{
    super.onCreate();
    isInCorrectState = true;
    }

    public void onPause() {
    super.onPause();
      if(isFinishing()){
        isInCorrectState = false;
       }
    }

现在使用此标志在附加片段之前检查您的活动是否处于正确状态。含义附加片段iff isInCorrectState == true

答案 5 :(得分:2)

对我而言,其他原因是其他原因。

在我的Loader.onLoaderReset()中,我清除了适配器中的数据。当我离开应用程序时,onDestroy()导致加载程序重置,这清除了FragmentStatePagerAdapter。我认为它导致适配器清除对它的片段的所有引用,但不知何故,FragmentManager没有注意到并抛出异常。对我来说似乎不合逻辑。

请注意,对我而言,它发生了Activity.onDestroy()

希望它有所帮助。

答案 6 :(得分:0)

ViewPager中的片段是固定的,而不是尝试替换适配器中的片段,尝试给出一组不同的片段并更改notifyDataSet,或者利用FrameLayout在视图分页器选项卡的当前片段上显示另一个片段

我的解决方案有效:

Swipe Gesture applied at Fragment level along with ViewPager with it's default swipe disabled