web-dev-qa-db-ja.com

FragmentPagerAdapterとFragmentStatePagerAdapterの違いは何ですか?

FragmentPagerAdapterFragmentStatePagerAdapterはどう違いますか?

FragmentPagerAdapterについてGoogleのガイドによると、

このバージョンのポケットベルは、タブセットなど、ページングする一般的により静的なフラグメントがいくつかある場合に最適です。表示されていないときはビュー階層が破壊される可能性がありますが、ユーザーがアクセスした各ページの断片はメモリに保持されます。フラグメントインスタンスは任意の量の状態を保持できるため、これにより大量のメモリが使用される可能性があります。より大きなページセットの場合は、FragmentStatePagerAdapterを検討してください。

そしてFragmentStatePagerAdapterについて:

このバージョンのポケットベルは、リストビューのように機能する、多数のページがある場合に便利です。ページがユーザーに表示されない場合、そのフラグメント全体が破壊され、そのフラグメントの保存された状態が維持されるだけです。これにより、ページ間の切り替え時のオーバーヘッドが増加する可能性がありますが、FragmentPagerAdapterに比べてページャは各訪問ページに関連付けられているメモリを大幅に削減できます。

だから私はちょうど3つの断片があります。しかし、それらはすべて大量のデータを持つ別々のモジュールです。

Fragment1は(ユーザーが入力する)いくつかのデータを処理し、それをアクティビティを介してFragment2に渡します。これは単純なListFragmentです。 Fragment3ListFragmentです。

だから私の質問はです:どのアダプタを使うべきですか? FragmentPagerAdapterまたはFragmentStatePagerAdapter

326
AlexMomotov

ドキュメントが言うように、このように考えてください。あなたが本のようなアプリケーションを実行しようとしているのなら、すべての断片を一度にメモリにロードしたくはないでしょう。ユーザが読んだときにFragmentsをロードして破棄したいです。この場合はFragmentStatePagerAdapterを使います。 (Bitmapsのように)大量のデータを含まない3つの「タブ」を表示しているだけなら、FragmentPagerAdapterが適しているかもしれません。また、デフォルトでViewPagerは3つのフラグメントをメモリにロードすることに注意してください。最初のAdapterView階層を破壊し、必要に応じてそれを再ロードするかもしれません、2番目のAdapterFragmentの状態を保存するだけで、その後ユーザーがそのページに戻った場合、状態は取得されます。

263
Emmanuel
  • FragmentPagerAdapterはフラグメント全体をメモリに格納します。大量のフラグメントがViewPagerで使用されると、メモリのオーバーヘッドが増加する可能性があります。

  • 反対に、FragmentStatePagerAdapterはフラグメントのsavedInstanceStateのみを保存し、フォーカスが失われたときにすべてのフラグメントを破棄します。

  • したがって、ウィジェット付きのフラグメントのように動的フラグメントを使用する必要がある場合は、それらのデータをFragmentStatePagerAdapterに格納することができるので、savedInstanceStateを使用する必要があります。

  • 反対に、兄弟FragmentPagerAdapterは、フラグメント全体をメモリに格納する必要があるときに使用する必要があります。

  • フラグメント全体がメモリに保持されると言うと、そのインスタンスは破壊されず、メモリのオーバーヘッドが発生します。したがって、FragmentPagerAdapterのフラグメント数が少ない場合にのみViewPagerを使用することをお勧めします。

  • フラグメントが静的であると、インスタンスが格納されるオブジェクトが大量に存在することはないため、さらに優れています。

もっと詳しく言うと、

FragmentStatePagerAdapter:

  • FragmentStatePagerAdapterを使用すると、不要なフラグメントは破棄されます。トランザクションは、フラグメントをアクティビティのFragmentManagerから完全に削除することを約束します。

  • FragmentStatePagerAdapterの状態は、それが破棄されたときにそれがあなたのフラグメントのBundleからsavedInstanceStateから節約されるという事実から来ています。

FragmentPagerAdapter:

  • 比較すると、FragmentPagerAdapterはそのようなことは何もしません。フラグメントが必要なくなったとき、.FragmentPagerAdapterはトランザクションでdetach(Fragment)の代わりにremove(Fragment)を呼び出します。

  • これはフラグメントのビューを破壊しますが、フラグメントのインスタンスはFragmentManager.の中で生きたままにしておきますので、FragmentPagerAdapterで作成されたフラグメントは決して破壊されません。

117
Stephen

ドキュメントにもこのページの回答にも明示的には記載されていませんが(@Narutoが暗示していても)、FragmentPagerAdapterはフラグメント内のデータが変更されてもフラグメントを更新しないということです。

そのため、表示するフラグメントの数が限られていても、フラグメントをリフレッシュできるようにしたい場合(たとえば、フラグメント内のlistViewを更新するためにクエリを再実行するなど)は、FragmentStatePagerAdapterを使用する必要があります。

ここで私が大事にしているのは、フラグメントの数とそれらが類似しているかどうかは必ずしも考慮すべき重要な側面ではないということです。あなたのフラグメントが動的かどうかも重要です。

34
JDenais

これは、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を使用することに違いはありません。

Githubのデモはこちら

28
Phan Van Linh

FragmentPagerAdapterはアダプタからフェッチされた以前のデータを格納し、FragmentStatePagerAdapterは実行されるたびにアダプタから新しい値を取得します。

14
vinay kumar

FragmentStatePagerAdapter = ViewPagerで多数のフラグメントに対応するため。このアダプタは、フラグメントがユーザーに表示されず、フラグメントのsavedInstanceStateのみが今後の使用のために保持されている場合にフラグメントを破棄します。この方法では、少量のメモリが使用され、動的フラグメントの場合により良いパフォーマンスが提供されます。

4
Dwivedi Ji