5

と を使用ViewPagerFragmentStatePagerAdapterてフラグメントを表示しています。最初に Fragment1 と Fragment2 の 2 つのフラグメントが追加され、3 番目のフラグメント Fragment3 がサーバーからの応答を受信した後に 2 番目の位置に追加されます。したがって、すべてのページが追加された後、これは ViewPager の一連のフラグメントである必要があります --> Fragment1、Fragment3、Fragment2。

問題は Fragment1 と Fragment3 が追加された後、アプリがサーバー呼び出しを行ってから 3 番目の Fragment を 2 番目の位置に追加すると、3 番目のフラグメントが追加された後でも、最初は 2 番目の 2 番目の位置にあった Fragment2 の古いコピーが表示されます。位置と 3 番目の位置には Fragment2 の新しいコピーがあります。そのため、Fragment3 ドットが ViewPager に表示されます。3 番目の Fragment を追加した後のシーケンス -- > Fragment1、Fragment2 の古いコピー、新しい Fragment2。

アクティビティをオーバーライドonSaveInstanceStateして呼び出しています。super.onSaveInstanceState

POSITION_NONEまた、から戻ってみましたgetItemPosition。ViewPager がフラグメントのコピーを保存することをどこかで読みました。また、デバッグを通じて、問題が再現されたときに ViewPager に Fragment2 の 2 つのコピーが含まれていることを確認しましたが、位置ごとに異なるフラグメントgetItemが返されましたが、2 番目の位置では古いフラグメントが表示されていました。FragmentStatePagerAdapterテスト目的で、getItem3 ページすべてが同じになるようにすべての位置に Fragment1 を返しましたが、その後も上記の手順で問題を再現すると、2 番目の位置に Fragment2 の古いコピーが表示されていました。

ViewPagerでは、古いフラグメントを保存しないようにクリアする方法。フラグメントのある古いコピーを保持しないように ViewPager を更新する方法。問題は onSaveInstanceState にあると思いますが、必要です。ViewPagerビューが に保存されているときに除外するにはどうすればよいですかonSaveInstanceState。試してみmViewPager.setSaveEnabled(false)ましたが、メモリが多すぎます。

instantiateItem古いフラグメントが返されるため、アダプターのメソッドが getItem を呼び出さないことが問題であることがわかりました。

以下はソリューションコードです

コード:

 @Override
        public Object instantiateItem(ViewGroup container, int position) {
            Object obj = super.instantiateItem(container, position);
            Fragment fragment = mFragments.get(position);

            if((obj!=null && fragment!=null) && !(obj.getClass().getSimpleName().equals(fragment.clss.getSimpleName()))){
                destroyItem(container, position, obj);
                return super.instantiateItem(container, position);
            }else{
                return obj;
            }
        }
4

2 に答える 2

1

私は問題を解決しました。ここに私の解決策を投稿しています。私はそれをオーバーライドinstantiateItemし、FragmentStatePagerAdapterその中でオブジェクトを取得super.instantiateItemし、そのクラス名を、私が維持しているフラグメントのリストからその位置にあるオブジェクトのクラス名と比較しています。

クラス名が同じでない場合、その意味super.instantiateItemは重複したフラグメントを返します。だから私はdestroyItemその位置で呼び出して、もう一度呼び出しsuper.instantiateItemてから返していinstantiateItemます。

FragmentStatePagerAdapterフレームワークコードのarraylistmFragmentsには重複したフラグメントがあり、現在の位置にあるフラグメントを返すだけなので、古いフラグメントを返します。リスト内の位置にあるフラグメントと、現在表示されているフラグメントを比較してから返す必要があると思います。

于 2013-11-01T10:17:18.257 に答える