適当プログラマー

Androidなんて嫌いだ。

【Android】Fragmentで画面を傾けた際に初期化しないようにsetRetainInstanceを使えって言うけど、うまく行かないときの対処法

Android。なぜこの世にAndroidというデバイスが存在するのか。そんなものが無ければ、私もAndroidプログラミングで苦労することなど無いのに。

Androidには、一般的に一つの画面を構成するActivityというものがあります。

でも、最近は「"一つの画面"をActivityで作成するより、"一つの画面に見せかけた部品"を使いまわした方が、スマートフォン、タブレット、両方に対応できるぜ!!」っていう話から、一つの画面に見せかけた部品、Fragmentが生まれました

で、Activity、Fragmentに関わらず、スマートフォンやタブレットは、アプリを画面に表示した状態で、そのデバイスを傾けると、画面が初期化されます。

でも、「デバイスを傾けた時に、画面を初期化したくない」というニーズも当然ありまして、Fragmentの場合には「setRetainInstanceを使え」っていう事になっています。

詳しくは、他の方のサイト『技術見聞録 - 縦横切り替えなどのConfigurationChangeで自動的にFragmentを復元させる』『画面回転時にレイアウトを動的に切り替える(Fragment再生成しない) - プログラマってこんなかんじ??』をご覧ください。

私も上記サイトや他のサイトをググりまくった結果、「要するにFragmentにおいてはsetRetainInstance(true);という一文を書くだけで、画面を傾けても初期化されないようになるんだな」という理解の下、一文を書いたさ!傾けてみたさ!初期化されたさ!!泣いたね!!

というわけで、解決法です。

画面を傾けると、ライフサイクルは一旦onDestroy()されてonCreate()から開始されます。

そして、あなたは多分、onCreateの中で

@Override
public void onCreate(Bundle savedInstanceState){
    super.onCreate(savedInstanceState);
    FragmentManager fragmentManager = getFragmentManager();
    FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
    Fragment1 fragment1 = new Fragment1();
    fragmentTransaction.replace(android.R.id.content, fragment1);
    fragmentTransaction.commit();
}

みたいに書いているのでしょう。そして、FragmentをextendsしたFragment1クラスの中で setRetinInstance(true)と書いていて、「なぜ初期化されるのだろう?」と悩んでいるのでしょう。

初期化されるに決まってるじゃない!!onCreate()を通っているのだから、再度Fragment1クラスを最初から生成しているに決まってるじゃない!!愚か者!!

正しい書き方はこうです。

@Override
public void onCreate(Bundle savedInstanceState){
    super.onCreate(savedInstanceState);
    if(null == savedInstanceState){
        FragmentManager fragmentManager = getFragmentManager();
        FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
        Fragment1 fragment1 = new Fragment1();
        fragmentTransaction.replace(android.R.id.content, fragment1);
        fragmentTransaction.commit();
    }
}

Fragmentの呼び出し元にif(null == savedInstanceState){ 〜 } という一文を追加しました。これさえあれば、もう画面が初期化される事はありません。

参考サイトはandroid - retain the fragment object while rotating - Stack Overflowになります。

このエントリーをはてなブックマークに追加