Android、Java、Web系、Linux、マラソン等の備忘録

2016/06/14

ViewPager + FragmentStatePagerAdapter画面回転時等のメモ

0 件のコメント
ViewPager + FragmentStatePagerAdapterの組み合わせでハマったのでメモしておきます。

Android端末画面回転時

主に、Android端末を倒して画面を回転させた時にgetItem()が呼ばれないとか、ViewPagerがFragmentを保持してるという仕様についてですが、保持して欲しくない時は以下をAdapter内に記述しておけばOKです。これで画面回転時にもgetItem()も呼ばれるようになります。

@Override
public Parcelable saveState() {
  return null;
}

ちなみに、Fragmentを直接削除したい場合はここ(Remove all fragments from ViewPager populated by FragmentStatePagerAdapter)で紹介されてるような方法もあります。

    List<Fragment> fragments = fragmentManager.getFragments();
   
if (fragments != null) {
       
FragmentTransaction ft = fragmentManager.beginTransaction();
       
for (Fragment f : fragments) {
           
//You can perform additional check to remove some (not all) fragments:
           
if (instanceof AddedByCurrentPagerAdapterFragment) {
                ft
.remove(f);
           
}
       
}
        ft
.commitAllowingStateLoss();

    }
Fragmentを削除してもAdapter的には保持している扱いのようなので注意(もうひと工夫?)が必要です。

instantiateItem()を扱う注意点

例えばネットワーク上のデータを取得後、ViewPager内のFragmentへデータを渡すような場合、このメソッドを実行すれば、ViewPager内の指定のポジションのFragmentを取得できますが、カレントポジションから離れてるFragmentは生成されていない(まだonCreateView()などが実行されていない)ので注意が必要です。TextViewなどへテキストをセットしようとするとNullPointerExceptionになります。Adapter側でデータを保持しつつ、現在生成されているFragmentには値セットするような実装が必要になるかと思います。

そもそもこのメソッドを使わず、Adapter側でデータを保持しつつFragment毎にメッセージレシーバを設けてメッセージを飛ばしてやるのも良いかもしれません。もちろん、Fragment側はViewが破棄されたらメッセージを受け付けないようにしておく必要があります。(FragmentのonDestroyView()あたりにunregisterReceiver()を実行するようにしておくと良いと思います。)


0 件のコメント :

コメントを投稿