61

適切な修正を実装するために、この例外を理解したいと思います。

ViewPager があり、FragmentStatePagerAdapter を使用して getItem と を介して 2 つのフラグメントをインスタンス化しますMyFragmentClass.newInstance(...)

アダプターの 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;
}

問題:

アクティビティが破棄され、再度作成されると、アダプターが再びインスタンス化され、フラグメントが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) に対応しておらず、例外がスローされます。

この背後にある考え方や、フラグメントをインスタンス化する方法がわかりません。

別のコンテキストから得たトリックを試しました:

pager.setOffscreenPageLimit(1);

フラグメントが画面外にあるときにフラグメントが破棄されるのを避けるため (2 ページのビューページャーの場合、状態アダプターでうまく機能するかどうかはわかりません)。しかし、関連していないようです。少なくとも、それは役に立ちません。それでも同じ例外が発生します。

例外をキャッチすると、ページが空白になります。

4

8 に答える 8

27

フラグメントが画面外にあるときに再利用されたくない場合は、FragmentPagerAdapterand notを使用する必要がありFragmentStatePagerAdapterます。

于 2012-09-04T20:07:41.103 に答える
4

私は一日中この問題に苦労していますが、今では解決策を見つけました。

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

setOffscreenPageLimitアイドル状態でビュー階層の現在のページの両側に保持するページ数を設定します。この制限を超えるページは、必要に応じてアダプターから再作成されます。

于 2016-03-19T18:02:45.093 に答える