ソースに絡まるエスカルゴ

貧弱プログラマの外部記憶装置です。

【Android Studio】備忘録#1 メッセージダイアログについて

最近ちょっとしたAndroidアプリでも作ってみるかと思い立ってAndroid Studioを触り始めました。「メッセージダイアログを表示させてOK、キャンセルで違う挙動をさせたい」と考えて調べてもすぐにはできない様子。

ググってコピペしていじってを繰り返してなんとか動くものができたので残しておこうと思った次第です。


1:メッセージダイアログ画面の作成

まずは表示させたいメッセージダイアログ画面を作成します。タイトル、内容、OK、CANCELの各要素があれば良いと思ったので以下のようにしました。

dialog.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    android:gravity="center"
    tools:context="com.test.test.util.CustomDialogFragment">

    <TextView
        android:id="@+id/dTitle"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginBottom="10dp"
        android:text="注意"
        android:textAlignment="center"
        android:textColor="?android:attr/editTextColor"
        android:textSize="30sp"
        android:textStyle="bold" />

    <TextView
        android:id="@+id/dMessage"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_marginBottom="10dp"
        android:text="dMessage"
        android:textColor="?android:attr/panelColorForeground"
        android:textSize="20sp" />

    <Button
        android:id="@+id/dOK"
        android:layout_width="350dp"
        android:layout_height="wrap_content"
        android:text="OK" />

    <Button
        android:id="@+id/dCancel"
        android:layout_width="350dp"
        android:layout_height="wrap_content"
        android:text="Cancel" />
</LinearLayout>

ちなみにプレビューは以下のとおり。
f:id:rikoubou:20170324204341p:plain



2:メッセージダイアログ画面を表示させるクラスの作成

CustomDialogFragmentという名前で以下のようにクラスを作成します。

CustomDialogFragment.java

/**
 * メッセージダイアログを表示させるクラス
 */
public class CustomDialogFragment extends DialogFragment {

    // 画面に設定するキー
    public static final String FIELD_TITLE = "title";
    public static final String FIELD_MESSAGE = "message";
    public static final String FIELD_LABEL_POSITIVE = "label_positive";
    public static final String FIELD_LABEL_NEGATIVE = "label_negative";

    @Override
    public Dialog onCreateDialog(Bundle savedInstanceState) {
        // ダイアログの設定
        Dialog dialog = new Dialog(getActivity());
        dialog.getWindow().requestFeature(Window.FEATURE_NO_TITLE);
        dialog.getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,
                WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN);
        dialog.setContentView(R.layout.dialog);
        dialog.getWindow().setBackgroundDrawable(new ColorDrawable(Color.argb(255, 255, 255, 255)));

        // 画面の各情報
        Bundle args = getArguments();

        // 各種画面の要素を取得
        TextView dTitle = (TextView)(dialog.findViewById(R.id.dTitle));
        TextView dMessage = (TextView)(dialog.findViewById(R.id.dMessage));
        Button dOK = (Button)(dialog.findViewById(R.id.dOK));
        Button dCancel = (Button)(dialog.findViewById(R.id.dCancel));

        // argsにある各文字列を設定
        if (args.containsKey(FIELD_TITLE)) {
            dTitle.setText(args.getString(FIELD_TITLE));
        }
        if (args.containsKey(FIELD_MESSAGE)) {
            dMessage.setText(args.getString(FIELD_MESSAGE));
        }
        if (args.containsKey(FIELD_LABEL_POSITIVE)) {
            dOK.setText(args.getString(FIELD_LABEL_POSITIVE));
        }
        if (args.containsKey(FIELD_LABEL_NEGATIVE)) {
            dCancel.setText(args.getString(FIELD_LABEL_NEGATIVE));
        }

        // OKボタンが押された時の処理
        dOK.setOnClickListener(new OnClickListener() {
            @Override
            public void onClick(View v) {
                IActivity callingActivity = (IActivity) getActivity();
                callingActivity.onReturnValue(true);
                dismiss();
            }
        });

        // キャンセルボタンが押された時の処理
        dCancel.setOnClickListener(new OnClickListener() {
            @Override
            public void onClick(View v) {
                IActivity callingActivity = (IActivity) getActivity();
                callingActivity.onReturnValue(false);
                dismiss();
            }
        });

        return dialog;
    }
}

簡単に説明すると、
タイトルやメッセージ、OKボタン、CANCELボタンに表示させる文字列は
Bundle argsで渡しているのでそれを取得して設定しています。

そしてボタンが押された場合、
呼び出し元に実装されているonReturnValue(boolean value)の引数valueに
OKならtrue、CANCELならfalseが渡されて実行されます。

IActivity.java

public interface IActivity {
    /**
     * OK/Cancelのダイアログの戻り処理
     * @param value true:OK、false:Cancel
     */
    public void onReturnValue(boolean value);
}

またIActivityというインターフェースを使うことで
呼び出し元でonReturnValueを実装するのを忘れないようにしています。


3:メッセージダイアログを呼び出す

実装したメッセージダイアログを呼び出す方法は以下の通りです。

MainActivity.java

public class MainActivity extends FragmentActivity implements IActivity {

     // 各要素に設定する文字列
     Bundle args = new Bundle();
     args.putString(CustomDialogFragment.FIELD_TITLE, "注意");  // タイトルの設定
     args.putString(CustomDialogFragment.FIELD_MESSAGE, "別の画面に移動します。\nよろしいですか?"); // メッセージの設定

     // メッセージダイアログ作成
     CustomDialogFragment cdf = new CustomDialogFragment();
     cdf.setArguments(args);
     cdf.show(getSupportFragmentManager(),"dialog");

    /**
     * OK/Cancelのダイアログの戻り処理
     * @param value true:OK、false:Cancel
     */
    public void onReturnValue(boolean value) {
        if (value) {
            // OKの場合の処理
            Intent intent = new Intent(getApplication(), SubActivity.class); // SubActivityの画面へ移動
            startActivity(intent);
        } else {
            // キャンセルの場合の処理
        } 
    }
}

上記の方法で自作のメッセージダイアログを作成し、
onReturnValueという関数の引数に結果が渡されるので
if文によって処理を変えることができます。

また別のクラスでもIActivityインターフェースを使うことで
同じようにメッセージダイアログを使うことができます。

これである程度は汎用的に扱えるようになったはずです。