Làm thế nào để xử lý nút Quay lại với trong hộp thoại?


95

Tôi đang phát triển một ứng dụng mà khi nhấn nút, nó sẽ mở ra một hộp thoại với các nút OK và Cancel.

Nó hoạt động tốt.

Khi người dùng nhấn nút quay lại, tôi đang xử lý điều này như sau

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

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

Nhưng phương thức trên không được gọi. Làm thế nào tôi có thể xử lý điều này?


1
Bạn có muốn người dùng có thể hủy hộp thoại không? Hoặc phần onKeyDown của bạn làm gì?
Krueger

@kiran :: bạn có thể nói rõ hơn một chút không ??
KMI

Câu trả lời:


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
không cần phải loại bỏ Dialog; finish()chăm sóc này đã. Ngoài ra, phương pháp này probaly nên trở lại falseđể có thể sự kiện phím chụp ảnh ở nơi khác
slinden77

6
Tôi nghĩ câu trả lời của alexc dưới đây là một sự thay thế tốt hơn.
Simon Forsberg

23
Tôi đã thêm && event.getAction() == KeyEvent.ACTION_UPcâu trả lời. Nếu không có nó, khối mã sẽ được thực thi hai lần. (Phím XUỐNG và phím LÊN). Trong ví dụ này, nó không quá quan trọng, nhưng đối với các hành động khác ngoài finish (), nó có thể rất quan trọng.
Udo Klimaschewski

1
@dmmh nếu bạn không gọi dialog.dismiss()sẽ bị rò rỉ bộ nhớ.
CONvid 19

2
Tôi chắc rằng bạn đúng, nhưng trong trường hợp đó finish()dialog.dismiss()nên được chuyển đổi trong đoạn mã trên.
slinden77

115

Có vẻ như bạn muốn đặt OnCancelListener khi bạn tạo Hộp thoại. Nó trông như thế này:

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

7
Đây chắc chắn là câu trả lời tốt nhất. Đẹp và đơn giản. Không cần phát hiện KeyEvent. Hoàn hảo.
LargeGlasses

2
Tôi biết mình đã quá muộn, nhưng tôi nghĩ hãy chỉ ra điều gì đó. Ngoài ra, điều này cũng sẽ được kích hoạt khi người dùng nhấp vào một nơi nào đó bên ngoài hộp thoại. Vì vậy, nếu bạn chỉ cần ghi đè tùy chọn back press thì đây không phải là thứ bạn đang tìm kiếm.
dùng2520215

5
@ user2520215 nếu bạn không muốn nó kích hoạt khi người dùng nhấp vào bên ngoài hộp thoại, bạn nên đặt hộp thoại.setCanceledOnTouchOutside (false). Đây chắc chắn là câu trả lời tốt hơn.
Alhassan Abdulkadir

Cảm ơn đã chỉ ra. Đây chắc chắn là một cách tiếp cận tốt hơn.
user2520215

3
Điều này dường như không hoạt động nếu một dạng xem tùy chỉnh được sử dụng (tức là không tạo hộp thoại mà chỉ kế thừa từ DialogFragment) trong khi trình nghe chính hoạt động trong trường hợp đó.
Julian Honma

19

Bạn cần ghi đè OnCancelphương thức. Phương thức này gọi khi nhấn Phím Quay lại. Đây là mã hoạt động hoàn hảo đối với tôi.

 AlertDialog alertDialog;

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

                    dialog.dismiss();                           

            }
}); 

Hy vọng điều này sẽ giúp bạn và chấp nhận nó nếu nó hữu ích cho bạn.

Cảm ơn..


7

Thử cái này

 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
Tại sao tôi không thể sử dụng setOnCancelListener trong Builder?
ffleandro

2

Nếu bạn đang sử dụng DialogFragment, từ những gì tôi có thể cho biết cách làm đúng là ghi đè onCancel ()

Tôi nhận thấy setOnCancelListenernó không hoạt động và setOnKeyListenerhoạt động, nhưng đối với tôi có một tác dụng phụ thú vị là nó nuốt tất cả các phím nếu hộp thoại của bạn có văn bản chỉnh sửa.


1

đó là vì khi Hộp thoại của bạn mở ra thì cửa sổ của bạn điều hướng tiêu điểm của nó đến Hộp thoại. Vì vậy, bây giờ bạn phải xử lý keytrên Hộp thoại của mình.


Mặc dù đúng, câu trả lời này không cung cấp nhiều thông tin về cách xử lý keytrong Hộp thoại.
Simon Forsberg

1

Ghi đè phương thức onBackPressed()trong hộp thoại của riêng bạn và sử dụng nó trong mã của bạn:

public class MyDialog extends Dialog {

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

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

Sử dụng:

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

0

Mã này hoạt động:

    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();
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.