Ngăn hộp thoại hoạt động Android đóng khi chạm bên ngoài


228

Tôi có một hoạt động đang sử dụng kiểu Theme.Dialog sao cho nó là một cửa sổ nổi trên một hoạt động khác. Tuy nhiên, khi tôi nhấp bên ngoài cửa sổ hộp thoại (trên hoạt động nền), hộp thoại sẽ đóng lại. Làm thế nào tôi có thể ngăn chặn hành vi này?


1
Tại sao bạn sẽ làm điều đó btw. NẾU hành vi bạn muốn là của một hộp thoại, tại sao không sử dụng hộp thoại? Đến với câu hỏi của bạn, tôi không nghĩ có một giải pháp cho vấn đề đó.
Kumar Bibek

Các hộp thoại @KumarBibek bị giới hạn khi nói đến các tùy chỉnh bố cục ... đó là lý do tại sao một hoạt động. Ngay cả các tài liệu dành cho nhà phát triển cũng đề xuất phương pháp này cho một tùy chỉnh linh hoạt
Leo

1
Và những gì OP muốn là một hộp thoại Modal , tức là một hộp thoại buộc người dùng phải trả lời, chẳng hạn như OK hoặc Có / Không. Người dùng không thể chỉ cần bấm vào.
Scott Biggie

Câu trả lời:


33

Điều này có thể giúp bạn. Đó là một cách để xử lý cảm ứng bên ngoài sự kiện:

Làm cách nào để hủy Hộp thoại theo chủ đề như Hoạt động khi được chạm bên ngoài cửa sổ?

Bằng cách bắt sự kiện và không làm gì, tôi nghĩ bạn có thể ngăn chặn việc đóng cửa. Nhưng dù lạ là gì, đó là hành vi mặc định của hộp thoại hoạt động của bạn nên không để tự đóng khi bạn chạm vào bên ngoài.

(PS: mã sử dụng WindowManager.LayoutParams)


1
Đối tượng không phải là một hộp thoại, đó là một Hoạt động sử dụng kiểu hộp thoại. Hoạt động không có phương thức này và không thể chuyển sang Hộp thoại.
Fergusmac

bài của bạn là hoàn toàn ngược lại với những gì được hỏi. Ông hỏi làm thế nào để ngăn chặn việc đóng cửa không làm thế nào để gây ra nó.
ChuckKelly

4
Đó là những gì anh ấy giải thích với "Bằng cách bắt sự kiện và không làm gì cả, tôi nghĩ bạn có thể ngăn chặn việc đóng cửa".
metter

4
vì một số lý do, sau khi thực hiện toàn bộ FLAG_NOT_MODAL, WATCH_OUTSIDE_TOUCH, liên lạc bên ngoài thực tế không đóng các hoạt động, nhưng nút phía sau hoạt động được nhấp. Bất cứ ý tưởng cho điều đó?
njzk2

Lưu ý rằng Hộp thoại có bóng (ít nhất là cho đến bây giờ (8.0)): nếu bạn nhấp vào bóng, Android sẽ hiểu rằng nhấp chuột giống như trong hộp thoại. Chỉ muốn chia sẻ điều này với thế giới, tôi đã mất 10 phút để có được nó.
Lorenzo Von Matterhorn

458

Để ngăn hộp thoại không bị tắt trên phím back, hãy sử dụng

dialog.setCancelable(false);

Và để ngăn hộp thoại bị loại bỏ khi chạm vào bên ngoài, hãy sử dụng

 dialog.setCanceledOnTouchOutside(false);

4
Câu trả lời này rất hữu ích nhưng câu hỏi này là về hoạt động sử dụng thuộc tính Theme.Dialog.
Paresh Mayani

15
Tôi biết khi tôi nhận ra thì đã quá muộn vì nó giúp được nhiều người nên đã không xóa nó.
Singhak

12
Tôi biết điều này không thực sự liên quan đến câu hỏi, nhưng điều này đã giúp tôi. Cảm ơn!
dennisdrew

5
Đây là câu trả lời tốt nhất. Tôi nghi ngờ hầu hết những người tìm thấy câu hỏi này đang tìm cách ngăn chặn tiêu chuẩn AlertDialogđóng cửa bên ngoài và đó là những gì câu trả lời này cung cấp.
aroth

20
Trên các phiên bản mới hơn của AlertDialog, bạn chỉ cần sử dụngsetCancelable(false)
Kobi Tate

120

Những gì bạn thực sự có là một Hoạt động (ngay cả khi nó trông giống như Hộp thoại), do đó bạn nên gọi setFinishOnTouchOutside(false) từ hoạt động của mình nếu bạn muốn giữ cho nó mở khi hoạt động nền được nhấp.

EDIT: Điều này chỉ hoạt động với API Android cấp 11 trở lên


4
Điều này không ngăn bạn nhấn nút "quay lại" trong hoạt động của bạn. Vì vậy, bạn cũng cần ghi đè onBackPressed()không làm gì trong cơ thể
Alex Bonel

Nó không ngăn nút "quay lại" trong hộp thoại Hoạt động mà không có onBackPression (). Hoạt động hoàn hảo với this.setFinishOnTouchOutside (false).
Kunalxigxag

68

Điều làm việc cho tôi là tạo ra DialogFragmentmột tập hợp thành không thể hủy được:

dialog.setCancelable(false);

1
Không hữu dụng. Câu hỏi này là về Hoạt động, không phải là Đối thoại.
Scott Biggie

20

Khi sử dụng hộp thoại làm hoạt động trong onCreate, hãy thêm

setFinishOnTouchOutside(false);

17

Đối với API 10 cao hơn, Hộp thoại biến mất khi chạm vào bên ngoài, trong khi ở mức thấp hơn API 11, Hộp thoại không biến mất. Để ngăn chặn điều này, bạn cần làm:

Trong styles.xml:<item name="android:windowCloseOnTouchOutside">false</item>

HOẶC LÀ

Trong onCreate()phương pháp, sử dụng:this.setFinishOnTouchOutside(false);

Lưu ý: đối với API 10 trở xuống, phương pháp này không có hiệu lực và không cần thiết.


14

Đặt hộp thoại có thể hủy thành sai là đủ và bạn chạm vào bên ngoài hộp thoại cảnh báo hoặc nhấp vào nút quay lại sẽ làm cho hộp thoại cảnh báo biến mất. Vì vậy, sử dụng cái này:

setCancelable(false)

Và chức năng khác là không cần thiết nữa: dialog.setCanceledOnTouchOutside(false);

Nếu bạn đang tạo một hộp thoại tạm thời và tự hỏi để đặt dòng mã này, đây là một ví dụ:

new AlertDialog.Builder(this)
                        .setTitle("Trial Version")
                        .setCancelable(false)
                        .setMessage("You are using trial version!")
                        .setIcon(R.drawable.time_left)
                        .setPositiveButton(android.R.string.yes, null).show();

12

Sử dụng mã này nó hoạt động cho tôi

 AlertDialog.Builder alertDialog = new AlertDialog.Builder(this);
 alertDialog.setCancelable(false);


Đây phải là câu trả lời đúng, nếu anh ta có thể làm đúng câu hỏi!
alijunior

2
Đây sẽ là câu trả lời chính xác, nếu OP hỏi về hộp thoại ! Nhưng câu hỏi là về Hoạt động - một trường hợp hoàn toàn khác.
Scott Biggie

11
Dialog dialog = new Dialog(context)
dialog.setCanceledOnTouchOutside(true); 
//use this to dismiss the dialog on outside click of dialog

dialog.setCanceledOnTouchOutside(false);
//use this for not to dismiss the dialog on outside click of dialog.

Xem liên kết này để biết thêm chi tiết về hộp thoại.

dialog.setCancelable(false);
//used to prevent the dismiss of dialog on backpress of that activity

dialog.setCancelable(true);
//used to dismiss the dialog on onbackpressed of that activity

Xin lưu ý rằng câu hỏi liên quan đến Hoạt động được sử dụng làm hộp thoại, KHÔNG phải là lớp Hộp thoại.
Scott Biggie

8

Đơn giản,

alertDialog.setCancelable(false);

ngăn người dùng nhấp vào bên ngoài Hộp thoại.


6

Hộp thoại cảnh báo không được dùng nữa nên sử dụng hộp thoại Hộp thoại = hộp thoại mới (cái này);

Để ngăn chặn sự đụng chạm bên ngoài

dialog.setCanceledOnTouchOutside(false);

5

Sử dụng setFinishOnTouchOutside(false)cho API> 11 và đừng lo lắng vì hành vi mặc định của Android mà hộp thoại theo chủ đề hoạt động sẽ không kết thúc khi chạm bên ngoài cho API <11 :) !! Chúc mừng !!


5

Tôi sử dụng điều này trong onCreate (), dường như hoạt động trên mọi phiên bản Android; đã thử nghiệm trên 5.0 và 4.4.x, không thể kiểm tra trên Gingerbread, các thiết bị Samsung (Lưu ý 1 đang chạy GB) theo cách này theo mặc định:

    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB)
    {
        setFinishOnTouchOutside(false);
    }
    else
    {
        getWindow().clearFlags(LayoutParams.FLAG_WATCH_OUTSIDE_TOUCH);
    }

    super.onCreate(savedInstanceState);

4
        alert.setCancelable(false);
        alert.setCanceledOnTouchOutside(false);

Tôi đoán điều này sẽ giúp bạn. Nó làm việc cho tôi


1
Cũng hãy cố gắng giải thích lý do tại sao điều này sẽ hoạt động ... Chỉ là một bãi chứa mã không phải là một câu trả lời tốt.
Codebender

3

Đây là giải pháp của tôi:

AlertDialog.Builder builder = new AlertDialog.Builder(this);
builder.setTitle("Select The Difficulty Level");
builder.setCancelable(false);

2

Cũng có thể chỉ định hành động thực hiện khác nhau trên HủyListListener:

alertDialog.setOnCancelListener(new DialogInterface.OnCancelListener(){                   
    @Override
    public void onCancel(DialogInterface dialogInterface) {
        //Your custom logic
    } 
});

Làm thế nào tôi có thể xác định nếu hủy được gọi vì nhấn bên ngoài hộp thoại cảnh báo?
cegprakash

Rất hữu ích để tạo các hành động tùy chỉnh khi nhấn bên ngoài hộp thoại cảnh báo!
Adam S.

1

Tôi đã phải đối mặt với cùng một vấn đề. Để xử lý nó, tôi đặt một OntouchListenerhộp thoại và không làm gì bên trong. Nhưng Dialog bỏ qua khi xoay màn hình quá. Để khắc phục, tôi đặt một biến để cho tôi biết nếu hộp thoại thường bị loại bỏ. Sau đó, tôi đặt một OnDismissListenerhộp thoại của mình và bên trong tôi kiểm tra biến. Nếu hộp thoại không hoạt động bình thường thì tôi không biết, nếu không tôi sẽ chạy lại hộp thoại (và đặt trạng thái của anh ấy như khi bỏ qua trong trường hợp của tôi).


1

builder.set Hủy được (sai);


công khai Mensaje (Xem v) {

    AlertDialog.Builder builder = new AlertDialog.Builder(this);
    builder.setTitle("¿Quieres ir a el Menú principal?");
    builder.setMessage("Al presionar SI iras a el menú y saldras de la materia.");
    builder.setPositiveButton("SI", null);
    builder.setNegativeButton("NO", null);
    builder.setCancelable(false);
    builder.show();
}

1
Chào Alex. Chào mừng bạn đến với StackOverflow và cảm ơn bạn đã trả lời. Bạn có thể vui lòng chỉnh sửa câu trả lời của mình để mô tả mã của bạn làm gì và cách giải quyết vấn đề của OP không? Mã chỉ có câu trả lời không được khuyến khích vì họ không dạy hoặc giải thích lý do . Cảm ơn bạn!
Tim Malone

-1

Đây là câu trả lời hoàn hảo cho tất cả các câu hỏi của bạn .... Hy vọng bạn thích mã hóa trong Android

new AlertDialog.Builder(this)
            .setTitle("Akshat Rastogi Is Great")
            .setCancelable(false)
            .setMessage("I am the best Android Programmer")
            .setPositiveButton("I agree", new DialogInterface.OnClickListener() {
                @Override
                public void onClick(DialogInterface dialog, int which) {
                    dialog.dismiss();

                }
            })
            .create().show();

Cảm ơn bạn vì đoạn mã này, có thể cung cấp một số trợ giúp hạn chế, ngay lập tức. Một lời giải thích phù hợp sẽ cải thiện đáng kể giá trị lâu dài của nó bằng cách chỉ ra lý do tại sao đây là một giải pháp tốt cho vấn đề và sẽ giúp nó hữu ích hơn cho những người đọc tương lai với những câu hỏi tương tự khác. Vui lòng chỉnh sửa câu trả lời của bạn để thêm một số giải thích, bao gồm các giả định bạn đã thực hiện.
Maximilian Peters
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.