LoginSignup
62

More than 5 years have passed since last update.

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

Last updated at Posted at 2014-12-30

前提

以下のレイアウトを元に DialogFragment を全画面表示に変更していきます。

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>

以下は ActivityDialogFragment を表示するコードです。

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 を普通に表示する

view_dialog.xmlLinearLayoutmatch_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

:two: Dialog の枠を残したまま全画面表示にする

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

:three: Dialog の枠を無くした状態で全画面表示にする

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

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

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

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) {
        // ここで薄暗さ0のスタイルを設定します
        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

:information_source: 補足

何故 DialogFragment を使うのか

AlertDialog だと

ActivityAlertDialog を表示した後に画面を回転すると、AlertDialog が消え去り logcatE/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 Screenshot_1507533552.png

DialogFragment であれば

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

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
62