대화 상자에서 뒤로 버튼을 처리하는 방법은 무엇입니까?


95

버튼을 누르면 확인 및 취소 버튼이있는 대화 상자를 여는 응용 프로그램을 개발 중입니다.

잘 작동합니다.

사용자가 뒤로 버튼을 누르면 다음과 같이 처리합니다.

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

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

그러나 위의 메서드는 호출되지 않습니다. 어떻게 처리 할 수 ​​있습니까?


1
사용자가 대화 상자를 취소 할 수 있도록 하시겠습니까? 아니면 onKeyDown 부분은 무엇을합니까?
Krueger

@kiran :: U 조금 더 명확 할 수 있습니까 ??
KMI

답변:


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
무시할 필요가 없습니다 Dialog. finish()이미 처리합니다. 또한이 메서드는 false다른 곳에서 주요 이벤트를 캡처 할 수 있도록 다시 돌아와야합니다
slinden77 2013 년

6
아래 alexc의 답변이 더 나은 대안이라고 생각합니다.
Simon Forsberg 2013 년

23
나는 && event.getAction() == KeyEvent.ACTION_UP대답에 추가했습니다 . 이것이 없으면 코드 블록이 두 번 실행됩니다. (키 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 압둘 카디르

지적 해 주셔서 감사합니다. 이것은 확실히 더 나은 접근 방식입니다.
user2520215 2015

3
이 경우 키 리스너가 작동하는 동안 사용자 정의보기가 사용되는 경우 (즉, 대화 상자를 생성하지 않고 DialogFragment에서 상속하는 경우) 작동하지 않는 것 같습니다.
Julian Honma

19

OnCancel메서드 를 재정의해야합니다 . 이 메서드는 뒤로 키 누름을 호출합니다. 나에게 완벽하게 작동하는 코드가 있습니다.

 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

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.