ダイアログで戻るボタンをどのように処理しますか?


95

ボタンを押すと[OK]ボタンと[キャンセル]ボタンのあるダイアログが開くアプリケーションを開発しています。

正常に動作します。

ユーザーが戻るボタンを押すと、次のように処理します

public boolean onKeyDown(int keyCode, KeyEvent event) 
{
    if ((keyCode == KeyEvent.KEYCODE_BACK)) 
    {

    }
 return super.onKeyDown(keyCode, event);
}

ただし、上記のメソッドは呼び出されません。どうすればこれを処理できますか?


1
ユーザーがダイアログをキャンセルできるようにしますか?または、onKeyDownパーツは何をしますか?
クルーガー2012

@kiran ::あなたはもう少し明確にすることができますか?
KMI 2012

回答:


238
dialog.setOnKeyListener(new Dialog.OnKeyListener() {

            @Override
            public boolean onKey(DialogInterface arg0, int keyCode,
                    KeyEvent event) {
                // TODO Auto-generated method stub
                if (keyCode == KeyEvent.KEYCODE_BACK) {
                    finish();
                    dialog.dismiss();
                }
                return true;
            }
        });

8
を閉じる必要はありませんDialogfinish()これはすでに処理されています。また、このメソッドはおそらくfalse他の場所で重要なイベントをキャプチャできるように戻るはずです
slinden77

6
以下のalexcの答えの方が良いと思います。
Simon Forsberg、2013

23
&& event.getAction() == KeyEvent.ACTION_UPは答えに追加しました。これがない場合、コードブロックは2回実行されます。(キーDOWNおよびキーUP)。この例ではそれほど重要ではありませんが、finish()以外のアクションでは、非常に重要な場合があります。
Udo Klimaschewski 2013年

1
@dmmhを呼び出さないとdialog.dismiss()、メモリリークが発生します。
CONvid19 2014年

2
私は、あなたがしている権利が、その場合には確信しているfinish()dialog.dismiss()、上記のコードで入れ替えする必要があります。
slinden77 2014

115

ダイアログを作成するときにOnCancelListenerを設定したいようです。次のようになります。

dialog.setOnCancelListener(new DialogInterface.OnCancelListener() {         
    @Override
    public void onCancel(DialogInterface dialog) {
        //do whatever you want the back key to do
    }
});

7
これが間違いなく最良の答えです。素敵でシンプル。KeyEventを検出する必要はありません。完璧です。
LargeGlasses 2015年

2
私は手遅れだと知っていますが、何かを指すと考えました。これは、ユーザーがダイアログの外側をクリックしたときにもトリガーされます。したがって、バックプレスオプションのみをオーバーライドする必要がある場合は、これはあなたが探しているものではありません。
user2520215

5
@ user2520215ユーザーがダイアログの外側をクリックしたときにトリガーされないようにするには、dialog.setCanceledOnTouchOutside(false)を設定する必要があります。これは間違いなくより良い答えです。
Alhassan Abdulkadir 2015年

ご指摘ありがとうございます。これは確かにより良いアプローチです。
user2520215 2015年

3
これは、カスタムビューが使用されている場合(つまり、ダイアログを作成せず、DialogFragmentから継承している場合)、キーリスナーが機能している場合は機能しないようです。
Julian

19

OnCancelメソッドをオーバーライドする必要があります。このメソッドは、Back Keyを押します。これが私にぴったりのコードです。

 AlertDialog alertDialog;

    alertDialog.setOnCancelListener(new OnCancelListener() 
    {                   
           @Override
            public void onCancel(DialogInterface dialog) 
             {
               // TODO Auto-generated method stub

                    dialog.dismiss();                           

            }
}); 

これがあなたに役立つことを願っており、それがあなたに役立つ場合はそれを受け入れます。

ありがとう。


7

これを試して

 new AlertDialog.Builder(this).setOnKeyListener(new DialogInterface.OnKeyListener() {

                        @Override
                        public boolean onKey(DialogInterface dialog, int keyCode, KeyEvent event) {

                            if(keyCode == KeyEvent.KEYCODE_BACK){
                                Logger.d(TAG, "--------- Do Something -----------");
                                return true;
                            }
                            return false;


                        }
                    })

1
BuilderでsetOnCancelListenerを使用できないのはなぜですか?
ffleandro


1

これは、ダイアログが開いたときに、ウィンドウがフォーカスされたダイアログに移動するためです。したがって、今度はkeyダイアログを処理する必要があります。


この回答は正しいですがkey、ダイアログでの処理方法についてはあまり情報を提供しません。
Simon Forsberg

1

onBackPressed()独自のダイアログでメソッドをオーバーライドし、コードで使用します。

public class MyDialog extends Dialog {

    public MyDialog(@NonNull Context context) {
        super(context);
    }

    @Override
    public void onBackPressed() {
        // Do what you want
    }
}

使用する:

MyDialog dlg = new MyDialog(context);
dlg.show();

0

このコードは機能します:

    Dialog dlg = new Dialog(thisAct, R.style.DialogTheme);
    dlg.setContentView(view);
    dlg.setCancelable(false);
    dlg.getWindow().setType(WindowManager.LayoutParams.TYPE_KEYGUARD_DIALOG);
    dlg.setOnKeyListener((arg0, keyCode, event) -> {
        Timber.d("onKey(%d)", keyCode);
        //{home intercepting
        if ((keyCode == KeyEvent.KEYCODE_HOME)) {
            Timber.i("HOME pressed");
            return true;
        }

        return true;
    });
    dlg.show();
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.