FragmentPagerAdapter
とFragmentStatePagerAdapter
はどう違いますか?
FragmentPagerAdapter
についてGoogleのガイドによると、
このバージョンのポケットベルは、タブセットなど、ページングする一般的により静的なフラグメントがいくつかある場合に最適です。表示されていないときはビュー階層が破壊される可能性がありますが、ユーザーがアクセスした各ページの断片はメモリに保持されます。フラグメントインスタンスは任意の量の状態を保持できるため、これにより大量のメモリが使用される可能性があります。より大きなページセットの場合は、
FragmentStatePagerAdapter
を検討してください。
そしてFragmentStatePagerAdapter
について:
このバージョンのポケットベルは、リストビューのように機能する、多数のページがある場合に便利です。ページがユーザーに表示されない場合、そのフラグメント全体が破壊され、そのフラグメントの保存された状態が維持されるだけです。これにより、ページ間の切り替え時のオーバーヘッドが増加する可能性がありますが、
FragmentPagerAdapter
に比べてページャは各訪問ページに関連付けられているメモリを大幅に削減できます。
だから私はちょうど3つの断片があります。しかし、それらはすべて大量のデータを持つ別々のモジュールです。
Fragment1
は(ユーザーが入力する)いくつかのデータを処理し、それをアクティビティを介してFragment2
に渡します。これは単純なListFragment
です。 Fragment3
もListFragment
です。
だから私の質問はです:どのアダプタを使うべきですか? FragmentPagerAdapter
またはFragmentStatePagerAdapter
ドキュメントが言うように、このように考えてください。あなたが本のようなアプリケーションを実行しようとしているのなら、すべての断片を一度にメモリにロードしたくはないでしょう。ユーザが読んだときにFragments
をロードして破棄したいです。この場合はFragmentStatePagerAdapter
を使います。 (Bitmaps
のように)大量のデータを含まない3つの「タブ」を表示しているだけなら、FragmentPagerAdapter
が適しているかもしれません。また、デフォルトでViewPager
は3つのフラグメントをメモリにロードすることに注意してください。最初のAdapter
はView
階層を破壊し、必要に応じてそれを再ロードするかもしれません、2番目のAdapter
はFragment
の状態を保存するだけで、その後ユーザーがそのページに戻った場合、状態は取得されます。
FragmentPagerAdapter
はフラグメント全体をメモリに格納します。大量のフラグメントがViewPager
で使用されると、メモリのオーバーヘッドが増加する可能性があります。
反対に、FragmentStatePagerAdapter
はフラグメントのsavedInstanceStateのみを保存し、フォーカスが失われたときにすべてのフラグメントを破棄します。
したがって、ウィジェット付きのフラグメントのように動的フラグメントを使用する必要がある場合は、それらのデータをFragmentStatePagerAdapter
に格納することができるので、savedInstanceState
を使用する必要があります。
反対に、兄弟FragmentPagerAdapter
は、フラグメント全体をメモリに格納する必要があるときに使用する必要があります。
フラグメント全体がメモリに保持されると言うと、そのインスタンスは破壊されず、メモリのオーバーヘッドが発生します。したがって、FragmentPagerAdapter
のフラグメント数が少ない場合にのみViewPager
を使用することをお勧めします。
フラグメントが静的であると、インスタンスが格納されるオブジェクトが大量に存在することはないため、さらに優れています。
もっと詳しく言うと、
FragmentStatePagerAdapter:
FragmentStatePagerAdapter
を使用すると、不要なフラグメントは破棄されます。トランザクションは、フラグメントをアクティビティのFragmentManager
から完全に削除することを約束します。
FragmentStatePagerAdapter
の状態は、それが破棄されたときにそれがあなたのフラグメントのBundle
からsavedInstanceState
から節約されるという事実から来ています。
FragmentPagerAdapter:
比較すると、FragmentPagerAdapter
はそのようなことは何もしません。フラグメントが必要なくなったとき、.FragmentPagerAdapter
はトランザクションでdetach(Fragment)
の代わりにremove(Fragment)
を呼び出します。
これはフラグメントのビューを破壊しますが、フラグメントのインスタンスはFragmentManager
.の中で生きたままにしておきますので、FragmentPagerAdapter
で作成されたフラグメントは決して破壊されません。
ドキュメントにもこのページの回答にも明示的には記載されていませんが(@Narutoが暗示していても)、FragmentPagerAdapter
はフラグメント内のデータが変更されてもフラグメントを更新しないということです。
そのため、表示するフラグメントの数が限られていても、フラグメントをリフレッシュできるようにしたい場合(たとえば、フラグメント内のlistViewを更新するためにクエリを再実行するなど)は、FragmentStatePagerAdapterを使用する必要があります。
ここで私が大事にしているのは、フラグメントの数とそれらが類似しているかどうかは必ずしも考慮すべき重要な側面ではないということです。あなたのフラグメントが動的かどうかも重要です。
これは、4つのフラグメントとoffscreenPageLimit = 1 (default value)
を持つViewPager
内の各フラグメントのログライフサイクルです。
FragmentStatePagerAdapter
フラグメント1(起動アクティビティ)に移動します
Fragment1: onCreateView
Fragment1: onStart
Fragment2: onCreateView
Fragment2: onStart
フラグメント2に進む
Fragment3: onCreateView
Fragment3: onStart
フラグメント3に進む
Fragment1: onStop
Fragment1: onDestroyView
Fragment1: onDestroy
Fragment1: onDetach
Fragment4: onCreateView
Fragment4: onStart
フラグメント4に進む
Fragment2: onStop
Fragment2: onDestroyView
Fragment2: onDestroy
FragmentPagerAdapter
フラグメント1(起動アクティビティ)に移動します
Fragment1: onCreateView
Fragment1: onStart
Fragment2: onCreateView
Fragment2: onStart
フラグメント2に進む
Fragment3: onCreateView
Fragment3: onStart
フラグメント3に進む
Fragment1: onStop
Fragment1: onDestroyView
Fragment4: onCreateView
Fragment4: onStart
フラグメント4に進む
Fragment2: onStop
Fragment2: onDestroyView
結論:FragmentStatePagerAdapter
はフラグメントがonDestroy
を超えたときにoffscreenPageLimit
を呼び出しますが、FragmentPagerAdapter
は呼び出しません。
注:FragmentStatePagerAdapter
には、パフォーマンスに役立つので、ページ数が多いのでViewPager
を使用することをお勧めします。
offscreenPageLimit
の例:
Fragment3に行くと、offscreenPageLimit = 1
なので、Fragment1(または持っていればFragment5)を破壊します。 offscreenPageLimit > 1
を設定しても破壊しません。
この例でoffscreenPageLimit=4
を設定した場合、タブを変更するときにFragmentがFragmentStatePagerAdapter
およびFragmentPagerAdapter
を呼び出すことはないため、onDestroyView
またはonDestroy
を使用することに違いはありません。
FragmentPagerAdapter
はアダプタからフェッチされた以前のデータを格納し、FragmentStatePagerAdapter
は実行されるたびにアダプタから新しい値を取得します。
FragmentStatePagerAdapter = ViewPagerで多数のフラグメントに対応するため。このアダプタは、フラグメントがユーザーに表示されず、フラグメントのsavedInstanceStateのみが今後の使用のために保持されている場合にフラグメントを破棄します。この方法では、少量のメモリが使用され、動的フラグメントの場合により良いパフォーマンスが提供されます。