ディスプレイ全体に DialogFragment を表示する方法（修正版）

# 前提

以下のレイアウトを元に [`DialogFragment`](https://developer.android.com/reference/android/app/DialogFragment.html) を全画面表示に変更していきます。

``` view_dialog.xml
<LinearLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:gravity="center"
    android:orientation="vertical">

    <LinearLayout
        android:layout_width="wrap_content"
        android:layout_height="0dp"
        android:layout_weight="1"
        android:gravity="center"
        android:orientation="vertical">

        <Button
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="ボタン①" />
    </LinearLayout>

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="0dp"
        android:layout_weight="1"
        android:gravity="center"
        android:orientation="vertical">

        <Button
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:text="ボタン②" />
    </LinearLayout>

</LinearLayout>
```

以下は [`Activity`](https://developer.android.com/reference/android/app/Activity.html) で [`DialogFragment`](https://developer.android.com/reference/android/app/DialogFragment.html) を表示するコードです。

``` MainActivity.java
public class MainActivity extends AppCompatActivity {

    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        // DialogFragment を表示します
        ExampleDialogFragment exampleDialogFragment = new ExampleDialogFragment();
        exampleDialogFragment.show(getSupportFragmentManager(),
                ExampleDialogFragment.class.getSimpleName());
    }
}
```

## :one: [`DialogFragment`](https://developer.android.com/reference/android/app/DialogFragment.html) を普通に表示する

[`view_dialog.xml`](https://qiita.com/84d010m08/items/90eba3d8652ee1696b90#%E5%89%8D%E6%8F%90) の [`LinearLayout`](https://developer.android.com/reference/android/widget/LinearLayout.html) に `match_parent`
 を指定しているにも関わらず、縦横共に余白が残っています。

``` ExampleDialogFragment.java
import android.app.Dialog;
import android.os.Bundle;
import android.support.annotation.NonNull;
import android.support.v4.app.DialogFragment;

public class ExampleDialogFragment extends DialogFragment {

    @NonNull
    @Override
    public Dialog onCreateDialog(Bundle savedInstanceState) {
        Dialog dialog = new Dialog(getActivity());
        dialog.setContentView(R.layout.view_dialog);

        return dialog;
    }
}
```

![Screenshot_2015-01-03-07-56-05.png](https://qiita-image-store.s3.amazonaws.com/0/6881/e3c002a6-e1a1-65f4-a6c4-ace5a4b7819b.png)

## :two: [`Dialog`](https://developer.android.com/reference/android/app/Dialog.html) の枠を残したまま全画面表示にする

``` ExampleDialogFragment.java
import android.app.Dialog;
import android.os.Bundle;
import android.support.annotation.NonNull;
import android.support.v4.app.DialogFragment;
import android.view.ViewGroup;

public class ExampleDialogFragment extends DialogFragment {

    @NonNull
    @Override
    public Dialog onCreateDialog(Bundle savedInstanceState) {
        Dialog dialog = new Dialog(getActivity());
        dialog.setContentView(R.layout.view_dialog);
        // DialogFragment のレイアウトを縦横共に全域まで広げます
        dialog.getWindow().setLayout(ViewGroup.LayoutParams.MATCH_PARENT,
                ViewGroup.LayoutParams.MATCH_PARENT);

        return dialog;
    }
}
```

![Screenshot_2015-01-03-07-57-00.png](https://qiita-image-store.s3.amazonaws.com/0/6881/6d18b0bd-340b-d540-5e94-b40fb8b2ba53.png)

## :three: [`Dialog`](https://developer.android.com/reference/android/app/Dialog.html) の枠を無くした状態で全画面表示にする

``` ExampleDialogFragment.java
import android.app.Dialog;
import android.graphics.Color;
import android.graphics.drawable.ColorDrawable;
import android.os.Bundle;
import android.support.annotation.NonNull;
import android.support.v4.app.DialogFragment;
import android.view.ViewGroup;
import android.view.Window;

public class ExampleDialogFragment extends DialogFragment {

    @NonNull
    @Override
    public Dialog onCreateDialog(Bundle savedInstanceState) {
        Dialog dialog = new Dialog(getActivity());
        // DialogFragment をタイトル無しにします
        dialog.requestWindowFeature(Window.FEATURE_NO_TITLE);
        dialog.setContentView(R.layout.view_dialog);
        // 背景を透明にします
        dialog.getWindow().setBackgroundDrawable(new ColorDrawable(Color.TRANSPARENT));
        dialog.getWindow().setLayout(ViewGroup.LayoutParams.MATCH_PARENT,
                ViewGroup.LayoutParams.MATCH_PARENT);

        return dialog;
    }
}
```

![Screenshot_2015-01-03-07-57-27.png](https://qiita-image-store.s3.amazonaws.com/0/6881/3f825137-da1c-6a74-752e-9098f86a462c.png)

## :four: 背景の薄暗さを消す

`values/styles.xml` に以下を追記して、薄暗さ(Dim)の値を０に設定します。

``` values/styles.xml
<style name="NoDimDialogFragmentStyle" parent="@android:style/Theme.Holo.Light.Dialog">
    <item name="android:backgroundDimAmount">0.0</item>
    <item name="android:backgroundDimEnabled">false</item>
</style>
```

``` ExampleDialogFragment.java
import android.app.Dialog;
import android.graphics.Color;
import android.graphics.drawable.ColorDrawable;
import android.os.Bundle;
import android.support.annotation.NonNull;
import android.support.v4.app.DialogFragment;
import android.view.ViewGroup;
import android.view.Window;

public class ExampleDialogFragment extends DialogFragment {

    @NonNull
    @Override
    public Dialog onCreateDialog(Bundle savedInstanceState) {
        // ここで薄暗さ０のスタイルを設定します
        Dialog dialog = new Dialog(getActivity(), R.style.NoDimDialogFragmentStyle);
        dialog.requestWindowFeature(Window.FEATURE_NO_TITLE);
        dialog.setContentView(R.layout.view_dialog);
        dialog.getWindow().setBackgroundDrawable(new ColorDrawable(Color.TRANSPARENT));
        dialog.getWindow().setLayout(ViewGroup.LayoutParams.MATCH_PARENT,
                ViewGroup.LayoutParams.MATCH_PARENT);

        return dialog;
    }
}
```

![Screenshot_2015-01-03-08-04-14.png](https://qiita-image-store.s3.amazonaws.com/0/6881/c8775d8c-ec8d-71ba-efb3-81ace756d8ec.png)

# :information_source: 補足

- リスナーについては「[DialogFragment のイベントを Activity とか Fragment に伝えたい。](http://slumbers99.blogspot.jp/2013/11/dialogfragment-activity-fragment.html)」に記載されている方法で設定しないと [Crashlytics](https://www.crashlytics.com/) にクラッシュレポートが大量送信されることになります
- 画像は全て Android 4.4.4 の [Nexus 7 (2013)](https://www.asus.com/jp/Tablets/Nexus_7_2013/) で表示したものです

## 何故 [`DialogFragment`](https://developer.android.com/reference/android/app/DialogFragment.html) を使うのか

### [`AlertDialog`](https://developer.android.com/reference/android/app/AlertDialog.html) だと

[`Activity`](https://developer.android.com/reference/android/app/Activity.html) で [`AlertDialog`](https://developer.android.com/reference/android/app/AlertDialog.html) を表示した後に画面を回転すると、[`AlertDialog`](https://developer.android.com/reference/android/app/AlertDialog.html) が消え去り [logcat](https://developer.android.com/studio/command-line/logcat.html) に `E/WindowManager: android.view.WindowLeaked` エラーが表示されます :sob:

``` MainActivity.java
import android.os.Bundle;
import android.support.annotation.Nullable;
import android.support.v7.app.AlertDialog;
import android.support.v7.app.AppCompatActivity;
import android.view.View;

public class MainActivity extends AppCompatActivity {

    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        findViewById(R.id.button).setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                new AlertDialog.Builder(MainActivity.this)
                        .setTitle("タイトル")
                        .setMessage("メッセージ")
                        .setPositiveButton("OK", null)
                        .show();
            }
        });
    }
}
```

| 図1. 画面回転前 | 図2. 画面回転後 |
|:------:|:-------:|
|![Screenshot_1507533549.png](https://qiita-image-store.s3.amazonaws.com/0/6881/e91d6210-3e80-2187-bd8f-a48c4c7c939d.png)|![Screenshot_1507533552.png](https://qiita-image-store.s3.amazonaws.com/0/6881/daaeaf09-579f-f92c-fb13-2e6969ef4e09.png)|

### [`DialogFragment`](https://developer.android.com/reference/android/app/DialogFragment.html) であれば

画面を回転しても表示状態が保持され、リークも発生しません :ok_woman: