android:configChanges=”orientation|screenSize”指定時の挙動

投稿者: Anonymous

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

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

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

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

解決

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

はい

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

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

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

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

追記

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

DialogFragment

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();
    }
}

**Fragment

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以外");
    }
}
回答者: Anonymous

Leave a Reply

Your email address will not be published. Required fields are marked *