Android

【Android】ダイアログを閉じるイベントを取得する方法

android_coffee

Androidアプリに表示するAlertDialogには、だいたい「OK」や「キャンセル」などのボタンをつけますよね。
ユーザーがそのボタンを押した際のイベントを取得して、クリックリスナーなどで次の処理を行ったりするのではないでしょうか。

しかし、ユーザーが必ずボタンを押してくれるとは限りません。
ダイアログの外側をタップしてダイアログを閉じる方も多いと思います。

私自身も、アプリを利用する際には、ついついダイアログの外側をタップして閉じることが多いです。
そちらの方がスマホを持つ手から近いこともあって、楽なんですよね。

この場合、ボタンが押された訳ではないので、ボタンに紐づけたクリックリスナーは動作しません。

その場合には、ダイアログを閉じるイベントにリスナーを紐づける必要があります。

今回はそのために用意されているsetOnDismissListenerを紹介しますね。

ダイアログが閉じるイベントを取得するにはsetOnDismissListenerを使う

ダイアログが閉じられた際のイベントはsetOnDismissListenerで取得できます。

以下のように実装してみましょう。

        new AlertDialog.Builder(this)
                .setTitle("タイトル")
                .setMessage("メッセージ")
                .setPositiveButton("OK", new DialogInterface.OnClickListener() {
                    @Override
                    public void onClick(DialogInterface dialog, int which) {
                        // OKが押下された際の処理
                        Log.i("MainActivity", "setPositiveButtonが呼ばれました。");
                    }
                })
                .setOnDismissListener(new DialogInterface.OnDismissListener() {
                    @Override
                    public void onDismiss(DialogInterface dialog) {
                        // ダイアログが閉じられた際の処理
                        Log.i("MainActivity", "setOnDismissListenerが呼ばれました。");
                    }
                })
                .show();

このように実装すると、方法が何であれ、ダイアログが閉じられた際には必ず以下のログが出力されます。

I/MainActivity: setOnDismissListenerが呼ばれました。

ダイアログが閉じられた際に画面の更新などの処理を行いたい場合は、この部分に処理を書けばOKですね。

ボタン以外で閉じた場合は、setOnDismissListenerよりsetOnCancelListenerが先に呼ばれる

以下のように、setPositiveButtonやsetOnCancelListenerなど、複数のイベントリスナーが設定されている状態でダイアログを閉じると、どのような順番でイベントが呼ばれるのでしょうか?

        new AlertDialog.Builder(this)
                .setTitle("タイトル")
                .setMessage("メッセージ")
                .setPositiveButton("OK", new DialogInterface.OnClickListener() {
                    @Override
                    public void onClick(DialogInterface dialog, int which) {
                        // OKが押下された際の処理
                        Log.i("MainActivity", "setPositiveButtonが呼ばれました。");
                    }
                })
                .setOnDismissListener(new DialogInterface.OnDismissListener() {
                    @Override
                    public void onDismiss(DialogInterface dialog) {
                        // ダイアログが閉じられた際の処理
                        Log.i("MainActivity", "setOnDismissListenerが呼ばれました。");
                    }
                })
                .setOnCancelListener(new DialogInterface.OnCancelListener() {
                    @Override
                    public void onCancel(DialogInterface dialog) {
                        // ダイアログがキャンセルされた際の処理
                        Log.i("MainActivity", "setOnCancelListenerが呼ばれました。");
                    }
                })
                .show();

この場合にOKボタンでダイアログを閉じると、ログは以下となります。

I/MainActivity: setPositiveButtonが呼ばれました。
I/MainActivity: setOnDismissListenerが呼ばれました。

つまり、イベントの順番はこうなります。

  1. setPositiveButton
  2. setOnDismissListener

また、ダイアログの外側をタップしたり、端末の戻るボタンを押したりしてダイアログを閉じた場合は、以下のような順番でログが出力されます。

I/MainActivity: setOnCancelListenerが呼ばれました。
I/MainActivity: setOnDismissListenerが呼ばれました。

つまり、こうですね。

  1. setOnCancelListener
  2. setOnDismissListener

実はsetOnCancelListenerの方が先に呼ばれているのです。
もし、キャンセルイベントで何か別の処理をやろうとしている場合は、setOnDismissListenerで行う処理と重複しないように気をつける必要があります。

終わりに

今回はsetOnDismissListenerについてご紹介しました。
ダイアログを閉じた際のイベントを取得する際には、このsetOnDismissListenerを使用すると便利ですよ。

ただし、setOnCancelListenerの方が先に呼ばれることに注意してください。

今回はここまでです。それでは。