Zapobiegaj zamykaniu okna dialogowego aktywności Androida po dotknięciu z zewnątrz

228

Mam działanie, które korzysta ze stylu Theme.Dialog, dzięki czemu jest to ruchome okno nad innym działaniem. Jednak gdy kliknę poza oknem dialogowym (w tle), okno dialogowe zostanie zamknięte. Jak mogę zatrzymać to zachowanie?

Fergusmac
źródło
1
Dlaczego miałbyś to zrobić? JEŚLI pożądane zachowanie dotyczy dialogu, dlaczego nie skorzystać z okna dialogowego? Jeśli chodzi o twoje pytanie, nie sądzę, że istnieje na to rozwiązanie.
Kumar Bibek
Dialogi @KumarBibek są ograniczone, jeśli chodzi o dostosowanie układu ... dlatego aktywność. Nawet dokumentacja dla programistów zaleca to podejście w celu elastycznego dostosowania
Leo
1
Tym, czego chce OP, jest okno modalne , tj. Okno dialogowe, które zmusza użytkownika do odpowiedzi, takie jak OK lub Tak / Nie. Użytkownik nie powinien być w stanie po prostu kliknąć.
Scott Biggs,

Odpowiedzi:

33

To może ci pomóc. Jest to sposób na obsługę dotyku zdarzenia zewnętrznego:

Jak anulować okno dialogowe takie jak Aktywność po dotknięciu za oknem?

Chwytając zdarzenie i nie robiąc nic, myślę, że możesz zapobiec zamknięciu. Dziwne jest jednak to, że domyślnym zachowaniem okna dialogowego aktywności nie powinno być zamykanie się po dotknięciu na zewnątrz.

(PS: kod używa WindowManager.LayoutParams)

Michel-F. Portzert
źródło
1
Obiekt nie jest oknem dialogowym, jest to działanie wykorzystujące styl okna dialogowego. Aktywność nie ma tej metody i nie można jej przesyłać do okna dialogowego.
Fergusmac
Twój post jest dokładnym przeciwieństwem pytania. zapytał, jak zapobiegać zamykaniu, a nie jak je powodować.
ChuckKelly,
4
Właśnie to wyjaśnił w „Łapiąc to wydarzenie i nic nie robiąc, myślę, że możesz zapobiec zamknięciu”.
metter
4
z jakiegoś powodu, po zrobieniu całego FLAG_NOT_MODAL, WATCH_OUTSIDE_TOUCH, dotyk zewnętrzny tak naprawdę nie zamyka działań, ale kliknięty jest przycisk stojący za działaniem. jakiś pomysł na to?
njzk2,
Pamiętaj, że okna dialogowe mają cień (przynajmniej do tej pory (8.0)): jeśli klikniesz cień, Android zinterpretuje to kliknięcie tak, jak w oknie dialogowym. Chciałem tylko podzielić się tym ze światem, zajęło mi to 10 minut.
Lorenzo Von Matterhorn
458

Aby zapobiec odrzuceniu okna dialogowego po naciśnięciu klawisza Wstecz, użyj tego

dialog.setCancelable(false);

Aby uniknąć odrzucenia okna dialogowego przy użyciu dotyku zewnętrznego, użyj tego

 dialog.setCanceledOnTouchOutside(false);
Singhak
źródło
4
Ta odpowiedź jest pomocna, ale pytanie dotyczy aktywności za pomocą atrybutu Theme.Dialog.
Paresh Mayani
15
Wiem, kiedy zdaję sobie sprawę, że jest już za późno, ponieważ pomaga wielu osobom, więc go nie usunąłem.
Singhak
12
Wiem, że to tak naprawdę nie dotyczyło pytania, ale pomogło mi to. Dzięki!
dennisdrew
5
To najlepsza odpowiedź. Podejrzewam, że większość osób, które znajdą to pytanie, szuka sposobu, aby zapobiec AlertDialogzamknięciu standardu za pomocą dotyku na zewnątrz, i to właśnie zapewnia ta odpowiedź.
aroth
20
W nowszych wersjach AlertDialog wystarczy użyćsetCancelable(false)
Kobi Tate
120

To, co faktycznie masz, to Działanie (nawet jeśli wygląda jak okno dialogowe), dlatego powinieneś zadzwonić setFinishOnTouchOutside(false)z tego działania, jeśli chcesz, aby było otwarte po kliknięciu działania w tle.

EDYCJA: Działa to tylko z Androidem API poziomu 11 lub wyższym

artex
źródło
4
Nie uniemożliwia to naciśnięcia przycisku „wstecz” w swojej aktywności. Musisz więc również pominąć onBackPressed()robienie niczego w jego ciele
Alex Bonel,
Nie zapobiega przyciskowi „wstecz” w tym oknie dialogowym Działanie bez funkcji onBackPressed (). Działa idealnie z this.setFinishOnTouchOutside (false).
Kunalxigxag
68

To, co zadziałało, to stworzenie DialogFragmentzestawu, którego nie można anulować:

dialog.setCancelable(false);
Petr
źródło
1
Niepomocne. To pytanie dotyczy działań, a nie dialogów.
Scott Biggs,
20

Gdy używasz okna dialogowego jako działania w onCreate, dodaj to

setFinishOnTouchOutside(false);
Ronny Shibley
źródło
17

W przypadku wyższego interfejsu API 10 okno dialogowe znika po dotknięciu na zewnątrz, natomiast w interfejsie niższym niż API 11 okno dialogowe nie znika. Aby temu zapobiec, musisz:

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

LUB

W onCreate()metodzie użyj:this.setFinishOnTouchOutside(false);

Uwaga: w przypadku API 10 i niższych ta metoda nie działa i nie jest potrzebna.

ilw
źródło
14

Wystarczy ustawić wartość parametru cancelable na false, a albo dotkniesz okna dialogowego alertu, albo klikniesz przycisk Wstecz, zniknie okno alertu. Więc użyj tego:

setCancelable(false)

A druga funkcja nie jest już konieczna: dialog.setCanceledOnTouchOutside(false);

Jeśli tworzysz tymczasowe okno dialogowe i zastanawiasz się nad umieszczeniem tego wiersza kodu, oto przykład:

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();
BillOverFlow
źródło
12

Użyj tego kodu, to działa dla mnie

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

Aslam Patel
źródło
to powinna być poprawna odpowiedź, jeśli mógłby zrobić prawidłowe pytanie!
alijunior
2
To byłaby poprawna odpowiedź, gdyby PO pytał o dialogi ! Ale pytanie dotyczy działań - zupełnie innego przypadku.
Scott Biggs,
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.

Obejrzyj ten link, aby uzyskać więcej informacji na temat okna dialogowego.

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
anand krish
źródło
Pamiętaj, że pytanie dotyczy działań używanych jako okna dialogowe, NIE klasy Dialog.
Scott Biggs,
8

Po prostu,

alertDialog.setCancelable(false);

uniemożliwić użytkownikowi kliknięcie poza oknem dialogowym.


źródło
6

Alert Dialog jest przestarzały, więc użyj Dialog dialog = new Dialog (this);

Aby zapobiec zbliżeniu na dotyk zewnętrzny

dialog.setCanceledOnTouchOutside(false);
Muhammed Fasil
źródło
5

Użyj setFinishOnTouchOutside(false)dla API> 11 i nie martw się, ponieważ domyślne zachowanie Androida, że ​​okno dialogowe o tematyce aktywności nie zostanie ukończone na zewnętrznym interfejsie dla API <11 :) !! Pozdrawiam !!

Vishal Pandey
źródło
5

Używam tego w onCreate (), wydaje się działać na dowolnej wersji Androida; testowane na 5.0 i 4.4.x, nie można testować na Gingerbread, urządzenia Samsung (Uwaga 1 z GB) domyślnie mają to w ten sposób:

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

    super.onCreate(savedInstanceState);
3c71
źródło
4
        alert.setCancelable(false);
        alert.setCanceledOnTouchOutside(false);

Myślę, że to ci pomoże. To zadziałało dla mnie

użytkownik2532065
źródło
1
Spróbuj także wyjaśnić, dlaczego to zadziała ... Tylko zrzut kodu nie jest dobrą odpowiedzią.
Codebender
3

Oto moje rozwiązanie:

AlertDialog.Builder builder = new AlertDialog.Builder(this);
builder.setTitle("Select The Difficulty Level");
builder.setCancelable(false);
Akhter Al Amin
źródło
2

Możliwe jest także przypisanie różnych akcji implementujących onCancelListener:

alertDialog.setOnCancelListener(new DialogInterface.OnCancelListener(){                   
    @Override
    public void onCancel(DialogInterface dialogInterface) {
        //Your custom logic
    } 
});
Adae Rodríguez
źródło
Jak mogę sprawdzić, czy anulowanie jest wywoływane z powodu stuknięcia poza oknem dialogowym alertu?
cegprakash
Bardzo pomocne w tworzeniu niestandardowych akcji po stuknięciu poza oknem dialogowym alertu!
Adam S.
1

Miałem ten sam problem. Aby sobie z tym poradzić, ustawiam OntouchListenerw oknie dialogowym i nic nie robię w środku. Ale okno dialogowe odrzuca się również podczas obracania ekranu. Aby to naprawić, ustawiam zmienną, która informuje mnie, czy okno dialogowe zwykle zostało zamknięte. Następnie ustawiam a OnDismissListenerw oknie dialogowym i sprawdzam zmienną. Jeśli okno dialogowe nie działa normalnie, nic nie robię, bo inaczej uruchamiam je ponownie (i w moim przypadku ustawiam jego stan jak w przypadku zwolnienia).

Madara
źródło
1

builder.setCancelable (false);


public void Mensaje (Zobacz 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();
}
Alex Skriivordemgentschenfelde
źródło
1
Cześć Aleks. Witamy w StackOverflow i dziękuję za odpowiedź. Czy możesz edytować swoją odpowiedź, aby opisać, co robi Twój kod i jak to rozwiązuje problem PO? Odpowiedzi tylko na kod są odradzane, ponieważ nie uczą ani nie wyjaśniają, dlaczego . Dziękuję Ci!
Tim Malone,
-1

To idealna odpowiedź na wszystkie pytania .... Mam nadzieję, że lubisz kodować w Androidzie

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();
Akshat Rasogi
źródło
Dziękujemy za ten fragment kodu, który może zapewnić ograniczoną, natychmiastową pomoc. Właściwe wyjaśnienie znacznie poprawiłoby jego długoterminową wartość, pokazując, dlaczego jest to dobre rozwiązanie problemu i uczyniłoby to bardziej użytecznym dla przyszłych czytelników z innymi podobnymi pytaniami. Edytuj swoją odpowiedź, aby dodać wyjaśnienie, w tym przyjęte założenia.
Maximilian Peters