12376


Androidアプリは画面を回転させるとFragmentが再生成されると聞いて、  
いっそのことActivityを再生成しないようにとAndroidManifest.xmlのactivityのところに  
`android:configChanges="orientation|screenSize"`を指定しました。  
これにより回転させてもスクロール位置が保たれているのでいいのですが、気になる点があります。

・この場合Fragmentも再生成されていないという考えで良いでしょうか？

・Fragmentに定義している(Bundleを経由していない)変数の値も保持されるようになったのですが、  
この場合はそういうものとして実装を行っても問題ないでしょうか？

・再生成させないようにしたことによるデメリットはありますか？


CC BY-SA 3.0
2015-07-15T04:18:40.270
12367
2015-07-16T02:39:11.367
9710
question
android android-fragments android-activity
android:configChanges="orientation|screenSize"指定時の挙動


> ・この場合Fragmentも再生成されていないという考えで良いでしょうか？

はい

> ・Fragmentに定義している(Bundleを経由していない)変数の値も保持されるようになったのですが、  
>  この場合はそういうものとして実装を行っても問題ないでしょうか？

いいえ。`configChanges`で指定した回転など以外にも破棄される場合があるので、それに備えて保存すべき状態は保存しましょう。  
具体的には、他のアプリを起動したりした場合、`Activity/Fragment`が破棄される場合があります。  
簡単に試す方法として、`Android`の「開発者向けオプション」→「アクティビティを保持しない」にチェックを付けてアプリを動かしてみてください。  
一旦ホームボタンでホーム画面に行ってからアプリに戻ったり、他の`Activity`から戻ってきたりすると再生成されるようになります。

> ・再生成させないようにしたことによるデメリットはありますか？

画面回転時に`Activity`のレイアウトを変えたい場合、縦用レイアウト、横用レイアウトを用意しておくだけで再生成時に勝手に切り替わります。再生成させない場合は自動でレイアウトを切換することはできません。

**追記**

`DialogFragment`に`setTargetFragment()`と`getTargetFragment()`があります。  
ボタンが押されたというイベントを受け取りたい`Fragment`を`setTargetFragment()`で指定して、`DialogFragment`で`getTargetFragment()`を取得すればいいと思います。

**DialogFragment**

[code]

    public class MessageDialog extends DialogFragment {
    
        public static MessageDialog newInstance() {
            return new MessageDialog();
        }
    
        public MessageDialog() {
        }
    
        public Dialog onCreateDialog(Bundle savedInstanceState) {
    
            DialogInterface.OnClickListener listener;
            try {
                // ターゲットとなるFragmentを取得
                listener = (DialogInterface.OnClickListener) getTargetFragment();
            } catch (ClassCastException e) {
                throw new ClassCastException(getTargetFragment().toString() + " must implement DialogInterface.OnClickListener");
            }
    
            AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
            builder.setTitle("Title");
            builder.setMessage("Message");
            builder.setPositiveButton("OK", listener);
            builder.setNegativeButton("Cancel", listener);
            return builder.create();
        }
    }
    
[/code]

**Fragment

[code]

    public class HogeFragment extends Fragment implements DialogInterface.OnClickListener {
    
    // 省略
    
        // メッセージダイアログを表示
        private void hogehoge() {
            MessageDialog dialog = MessageDialog.newInstance();
            // 結果を受け取りたいFragmentを指定
            dialog.setTargetFragment(this, 0);
            dialog.show(getSupportFragmentManager(), null);
        }
    
        @Override
        public void onClick(DialogInterface dialog, int which) {
            Log.v(getClass().getSimpleName(), which == DialogInterface.BUTTON_POSITIVE ? "OKが押された" : "OK以外");
        }
    }
    
[/code]


CC BY-SA 3.0
2015-07-15T07:26:08.237
12376
2015-07-16T02:39:11.367
2015-07-16T02:39:11.367
8216
8216
12367
answer