getItemPosition(Object object)
ページを並べ替える目的でオーバーライドすると、 FragmentStatePagerAdapter が正しく動作しないと思います。
以下は簡単な例です。初期状態では、ページの順番は{A, B, C}です。を呼び出すtoggleState()
と、ページの順序が {A, C, B} に変わります。をオーバーライドgetItemPosition(Object object)
することで、現在表示されているページ (A、B、または C) が変更されないようにします。
public static class TestPagerAdapter extends FragmentStatePagerAdapter {
private boolean mState = true;
public TestPagerAdapter(FragmentManager fragmentManager) {
super(fragmentManager);
}
@Override
public int getCount() {
return 3;
}
private void toggleState() {
mState = !mState;
notifyDataSetChanged();
}
private String getLabel(int position) {
switch (position) {
case 0:
return "A";
case 1:
return mState ? "B" : "C";
default:
return mState ? "C" : "B";
}
}
@Override
public int getItemPosition(Object object) {
String label = ((TestFragment) object).getLabel();
if (label.equals("A")) {
return 0;
} else if (label.equals("B")) {
return mState ? 1 : 2;
} else {
return mState ? 2 : 1;
}
}
@Override
public CharSequence getPageTitle(int position) {
return getLabel(position);
}
@Override
public Fragment getItem(int position) {
return TestFragment.newInstance(getLabel(position));
}
}
間違っていると思われる 2 つの異なる動作に遭遇しました。
すぐに呼び出すと
toggleState()
(ページ A を表示しているときに、他のページにスワイプする前に)、アプリがクラッシュします。java.lang.IndexOutOfBoundsException: Invalid index 2, size is 2 at java.util.ArrayList.throwIndexOutOfBoundsException(ArrayList.java:251) at java.util.ArrayList.set(ArrayList.java:477) at android.support.v4.app.FragmentStatePagerAdapter.destroyItem(FragmentStatePagerAdapter.java:136) at android.support.v4.view.ViewPager.populate(ViewPager.java:867) at android.support.v4.view.ViewPager.setCurrentItemInternal(ViewPager.java:469) at android.support.v4.view.ViewPager.setCurrentItemInternal(ViewPager.java:441) at android.support.v4.view.ViewPager.dataSetChanged(ViewPager.java:766) at android.support.v4.view.ViewPager$PagerObserver.onChanged(ViewPager.java:2519) at android.database.DataSetObservable.notifyChanged(DataSetObservable.java:37) at android.support.v4.view.PagerAdapter.notifyDataSetChanged(PagerAdapter.java:276) at com.ugglynoodle.test.testfragmentstatepageradapter.MainActivity$TestPagerAdapter.toggleState(MainActivity.java:55) ...
のソースを見ると、これは136 行で呼び出す前に (113 ~ 115 行
FragmentStatePagerAdapter
のように) のサイズを最初にチェックすることで修正されます。mFragments
set()
最初にページ B にスワイプしてから
getItem(2)
呼び出されると、ページ C が作成され、mFragments
サイズが 3 になりました (これにより、上記のクラッシュがすぐに発生するのを防ぐことができます)。次に、スワイプしてページ A に戻ると、ページ C が破棄されます (2 ページ離れているため、デフォルトのオフスクリーン ページ制限 1 を使用しているため)。今、私は電話しますtoggleState()
。ページ B は現在破棄されています。ただし、ページ C は再作成されません。つまり、右にスワイプすると空のページが表示されます。
まず、私が正しくてこれらが実際にバグなのか、それとも私が何か間違ったことをしているのかを知ることができればうれしいです. それらがバグである場合、誰かが回避策を提案できますか (サポート ライブラリを自分でデバッグして再構築する以外に)。確かに、誰かがgetItemPosition(Object object)
正常にオーバーライドしたに違いありません (すべてを に設定することは別としてPOSITION_NONE
)?
サポート ライブラリの現在のリビジョン (10) を使用しています。