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


375

違いは何であるFragmentPagerAdapterとはFragmentStatePagerAdapter

FragmentPagerAdapterGoogleのガイドについて言う:

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

そして約FragmentStatePagerAdapter

このバージョンのページャーは、ページ数が多く、リストビューのように機能する場合により便利です。ページがユーザーに表示されない場合、フラグメント全体が破棄され、そのフラグメントの保存された状態のみが維持されます。これにより、ページャーは、ページをFragmentPagerAdapter切り替えるときにオーバーヘッドが増える可能性があるという犠牲を払って、訪問した各ページに関連付けられているメモリをはるかに少なく抑えることができ ます。

だから私はたった3つの断片を持っています。しかし、それらはすべて、大量のデータを持つ個別のモジュールです。

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

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


2
FragmentPagerAdapterを使用する資格は、フラグメントが3つしかないことだと思います。これらのフラグメントのタブはおそらく同時にすべて表示されます。
IgorGanapolsky

2
私は間違ったタイプのアダプターを使用したため、この投稿は5〜6時間節約しました
Nantaphop

1
この質問への答えは1より多くの質問を投げstackoverflow.com/questions/9156406/...
Piyush Kukadiya

ありますがFragmentPagerAdapterFragmentStatePagerAdapterFragmentStateAdapterですか?
the_prole

回答:


292

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


Fragment1とListViewに複数のボタンとTextViewがあり、Fragment2とFragment3に項目を動的に生成します。FragmentStatePagerAdapterを使用してすべてのデータをActivityに格納し、バンドルを介してFragmentsに渡すことは良い考えだと思いますか?
AlexMomotov

2
フラグメントのレイアウトの@AlexMomotovビューは、FragmentStatePagerAdapterの選択とは何の関係もありません。ここでの問題は、ページングされるフラグメントの量です。
IgorGanapolsky

1
だから基本的にFragmentPagerAdapterそれを使用することに賛成することは何もありません。
Tomasz Mularczyk 2015

3
@Tomaszの利点はFragmentPagerAdapter、実際のFragmentオブジェクトを毎回再構築する必要がないため、フラグメント間の切り替えがはるかに速くなることです。一方、フラグメントオブジェクトをメモリに保持しているメモリをより多く使用することになります。
Richard Le Mesurier 2016年

私は3つのタブ/ページ(それぞれがWebViewを表示する)を持っているので、FragmentPagerAdapterを使用しました。ただし、最初のページから最後のページにスワイプすると、最後のページが再描画されます。これを解決するために、私はを使用しましたviewPager.setOffscreenPageLimit(2)
ban-geoengineering

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

  • 兄弟とは逆に、FragmentStatePagerAdapterフラグメントのsavedInstanceStateのみを保存し、フォーカスを失ったときにすべてのフラグメントを破棄します。

  • したがってFragmentStatePagerAdapter、ウィジェットを含むフラグメントのように動的フラグメントを使用する必要がある場合は、それらのデータをsavedInstanceState

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

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

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

詳しくは

FragmentStatePagerAdapter:

  • を使用するとFragmentStatePagerAdapter、不要なフラグメントが破棄されますFragmentManager。トランザクションは、アクティビティのフラグメントを完全に削除するためにコミットされます。

  • 状態はFragmentStatePagerAdapter、フラグメントが破棄さBundleれたsavedInstanceStateときからフラグメントを保存するという事実から来ています。ユーザーが戻ると、フラグメントの状態を使用して新しいフラグメントが復元されます。

FragmentPagerAdapter:

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

  • これは、破壊するフラグメントの見解だが、中に生きているフラグメントのインスタンスを残しFragmentManagerで作成した断片の.so FragmentPagerAdapter破壊されることはありません。


2
なぜ2つの答えがあるのですか?
Jared Burrows 2014年

フラグメント全体をメモリに保持する利点は何ですか?
Tomasz Mularczyk 2015

4
@Tomek:次のフラグメントがすでにインスタンス化されている場合(つまり、FragmentPagerAdapter)、スワイプするとレンダリングする準備ができるので、スワイプアニメーションがよりスムーズになります。FragmentStatePagerAdapterを使用すると、スワイプするまで次のフラグメントインスタンスが存在しない可能性があり、作成にコストがかかる大きなフラグメントである場合、アニメーションが途切れることがあります。これは、パフォーマンスとメモリ消費の問題です。
ダルベルギア2015

1
1だけであるbcozバローズ@Jared AnswerText小さく、静的答えのために良いであり、他はあるAnswerStateText大きく、ダイナミックな答えです
シンプルフェロー

48

ViewPagerこれは、4つのフラグメントがあり、4 つのフラグメントがある各フラグメントのログライフサイクルです。offscreenPageLimit = 1 (default value)

FragmentStatePagerAdapter

Fragment1(起動アクティビティ)に移動します

Fragment1: onCreateView
Fragment1: onStart
Fragment2: onCreateView
Fragment2: onStart

Fragment2に移動

Fragment3: onCreateView
Fragment3: onStart

Fragment3に移動

Fragment1: onStop
Fragment1: onDestroyView
Fragment1: onDestroy
Fragment1: onDetach
Fragment4: onCreateView
Fragment4: onStart

Fragment4に移動

Fragment2: onStop
Fragment2: onDestroyView
Fragment2: onDestroy

FragmentPagerAdapter

Fragment1(起動アクティビティ)に移動します

Fragment1: onCreateView
Fragment1: onStart
Fragment2: onCreateView
Fragment2: onStart

Fragment2に移動

Fragment3: onCreateView
Fragment3: onStart

Fragment3に移動

Fragment1: onStop
Fragment1: onDestroyView
Fragment4: onCreateView
Fragment4: onStart

Fragment4に移動

Fragment2: onStop
Fragment2: onDestroyView

結論:Fragmentが克服されていないときにFragmentStatePagerAdapter呼び出します。 onDestroyoffscreenPageLimitFragmentPagerAdapter

:私は、私たちが使うべきだと思うFragmentStatePagerAdapterのためにViewPager、それは、パフォーマンスのために善意ため、ページの多くを持っています。

offscreenPageLimit

Fragment3に移動すると、Fragment1(または、存在する場合はFragment5)破棄されoffscreenPageLimit = 1ます。設定しoffscreenPageLimit > 1破壊されません
この例でを設定した場合、offscreenPageLimit=4使用するFragmentStatePagerAdapterFragmentPagerAdapter、Fragmentが呼び出されないためonDestroyViewonDestroyタブを変更したときとの間に違いはありません。

Githubデモはこちら


とても素晴らしい結論です!
Rahul Rastogi、

素晴らしい説明
グーラフシンハル

1
いい説明。ページ数が多いときにFragmentStatePagerAdapterを使用すると、パフォーマンスが向上するとおっしゃっていました。メモリ節約に良いということですか?私が理解している目標は、フラグメントインスタンスが多数発生する可能性がある場合にメモリを保持することです。つまり、パフォーマンスが暗黙の利点です。明確な目標は記憶を保存することです
Hatzil

38

ドキュメントまたはこのページの回答で明示的に述べられていないものは(@Narutoによって暗示されていても)、FragmentPagerAdapterフラグメントをメモリに保持するため、フラグメント内のデータが変更されてもフラグメントを更新しません。

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

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


つまり、フラグメントAの2つのフラグメント、1つのrecyclerviewがあるとします。アイテムをクリックすると、フラグメントBのコンテンツが変更されます。たとえば、fragB.setText( "blablabla")を実行します。状態pagerthenを使用する必要がありますか?
2015

確かではありませんが、そうだと思います。両方を試してみてください。コードを1つから別のコードに変更するのは本当に簡単で迅速です。
JDenais

@JDenaisこれは正しいですか?私が使用していFragmentPagerAdapterた各フラグメントはリストが含まれています-二つの断片を表示するViewPagerを使用して、私の活動に。私の最初のリストは「すべてのレポート」と呼ばれ、2番目のリストは「お気に入りレポート」です。最初のリストで、レポートのスターアイコンをタップすると、データベースが更新され、そのレポートのお気に入りのステータスが切り替わります。次にスワイプすると、2番目のリストのUIにこのレポートが正常に表示されます。したがって、インスタンスはメモリに保持されている可能性がありますが、場合によっては(例:私の場合)FragmentPagerAdapterのコンテンツは実際に正常に更新されます
ban-geoengineering

14

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


4

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


1

FragmentPagerAdapter:ユーザーがアクセスする各ページのフラグメントはメモリに格納されますが、ビューは破棄されます。そのため、ページが再び表示されると、ビューは再作成されますが、フラグメントインスタンスは再作成されません。これにより、大量のメモリが使用される可能性があります。FragmentPagerAdapterは、フラグメント全体をメモリに格納する必要がある場合に使用する必要があります。FragmentPagerAdapterは、remove(Fragment)ではなく、トランザクションでdetach(Fragment)を呼び出します。

FragmentStatePagerAdapter:フラグメントのインスタンスは、フラグメントの保存された状態を除いて、ユーザーに表示されないときに破棄されます。これにより、メモリの使用量が少なくなり、より大きなデータセットを処理するのに役立ちます。ウィジェットを含むフラグメントのように動的フラグメントを使用する必要がある場合は、それらのデータがsavedInstanceStateに格納される可能性があるため、使用する必要があります。また、フラグメントが多数あってもパフォーマンスに影響しません。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.