Impedisci la chiusura della finestra di dialogo delle attività Android al tocco esterno


229

Ho un'attività che utilizza lo stile Theme.Dialog in modo che sia una finestra mobile su un'altra attività. Tuttavia, quando faccio clic all'esterno della finestra di dialogo (sull'attività in background), la finestra di dialogo si chiude. Come posso fermare questo comportamento?


1
Perché dovresti farlo tra l'altro. SE il comportamento desiderato è di una finestra di dialogo, perché non utilizzare una finestra di dialogo? Venendo alla tua domanda, non penso che ci sia una soluzione a questo.
Kumar Bibek,

Le finestre di dialogo @KumarBibek sono limitate quando si tratta di personalizzazioni del layout ... ecco perché un'attività. Anche i documenti per sviluppatori raccomandano questo approccio per una personalizzazione flessibile
Leo,

1
E ciò che l'OP vuole è una finestra di dialogo modale , ovvero una finestra di dialogo che forza l'utente a rispondere, come OK o Sì / No. L'utente non dovrebbe essere in grado di fare clic.
Scott Biggs,

Risposte:


34

Questo potrebbe aiutarti. È un modo per gestire il tocco all'esterno dell'evento:

Come annullare una finestra di dialogo come Attività quando toccata fuori dalla finestra?

Catturando l'evento e non facendo nulla, penso che tu possa impedire la chiusura. Ma ciò che è strano, è che il comportamento predefinito della finestra di dialogo dell'attività dovrebbe essere quello di non chiudersi quando si tocca l'esterno.

(PS: il codice utilizza WindowManager.LayoutParams)


1
Tuttavia, l'oggetto non è una finestra di dialogo, è un'attività che utilizza lo stile della finestra di dialogo. L'attività non ha questo metodo e non può essere trasmessa a Dialog.
Fergusmac,

il tuo post è l'esatto contrario di ciò che è stato chiesto. ha chiesto come impedire la chiusura e non come causarlo.
ChuckKelly,

4
Il che è ciò che ha spiegato con "Catturando l'evento e non facendo nulla, penso che tu possa impedire la chiusura".
Metter

4
per qualche motivo, dopo aver eseguito l'intero FLAG_NOT_MODAL, WATCH_OUTSIDE_TOUCH, il tocco esterno non chiude le attività, ma si fa clic sul pulsante dietro l'attività. qualche idea per quello?
njzk2,

Nota che le finestre di dialogo hanno un'ombra (almeno fino ad ora (8.0)): se fai clic sull'ombra Android interpreterà quel clic proprio come all'interno della finestra di dialogo. Volevo solo condividere questo con il mondo, mi ci sono voluti 10 minuti per ottenerlo.
Lorenzo Von Matterhorn,

458

Per evitare che la finestra di dialogo venga respinta sul tasto Indietro premuto, utilizzare questo

dialog.setCancelable(false);

E per evitare che la finestra di dialogo venga ignorata al tocco esterno, utilizzare questa opzione

 dialog.setCanceledOnTouchOutside(false);

4
Questa risposta è utile ma questa domanda riguarda l'attività che utilizza l'attributo Theme.Dialog.
Paresh Mayani,

15
So quando mi rendo conto che è troppo tardi perché aiuta molte persone, quindi non lo ha eliminato.
Singhak,

12
So che questo non riguardava davvero la domanda, ma questo mi ha aiutato. Grazie!
dennisdrew,

5
Questa è la risposta migliore Sospetto che la maggior parte delle persone che trovano questa domanda stiano cercando un modo per impedire che lo standard si AlertDialogchiuda al tatto all'esterno, ed è ciò che fornisce questa risposta.
aroth

20
Nelle versioni più recenti di AlertDialog, devi solo usaresetCancelable(false)
Kobi Tate il

120

Quello che hai effettivamente è un'attività (anche se sembra una finestra di dialogo), quindi dovresti chiamare setFinishOnTouchOutside(false)dalla tua attività se vuoi tenerla aperta quando fai clic sull'attività in background.

EDIT: funziona solo con API Android di livello 11 o superiore


4
Questo non ti impedisce di premere il pulsante "indietro" nella tua attività. Quindi devi anche ignorare onBackPressed()non fare nulla nel suo corpo
Alex Bonel,

Non impedisce il pulsante "indietro" nella finestra di dialogo Attività senza onBackPressed (). Funziona perfettamente con this.setFinishOnTouchOutside (false).
Kunalxigxag

68

Ciò che ha funzionato per me è stato creare DialogFragmentun set per non essere cancellabile:

dialog.setCancelable(false);

1
Non d'aiuto. Questa domanda riguarda le attività, non le finestre di dialogo.
Scott Biggs,

20

Quando si utilizza la finestra di dialogo come attività in onCreate, aggiungere questo

setFinishOnTouchOutside(false);

17

Per API 10 superiori, la finestra di dialogo scompare quando toccata all'esterno, mentre in API inferiore 11, la finestra di dialogo non scompare. Per evitare ciò, devi fare:

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

O

Nel onCreate()metodo, utilizzare:this.setFinishOnTouchOutside(false);

Nota: per API 10 e precedenti, questo metodo non ha effetto e non è necessario.


14

L'impostazione della finestra di dialogo annullabile su false è sufficiente e sia che si tocchi all'esterno della finestra di avviso o si faccia clic sul pulsante Indietro, la finestra di avviso scompare. Quindi usa questo:

setCancelable(false)

E l'altra funzione non è più necessaria: dialog.setCanceledOnTouchOutside(false);

Se stai creando una finestra di dialogo temporanea e ti stai chiedendo di inserire questa riga di codice, ecco un esempio:

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

Usa questo codice per me funziona

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


questa dovrebbe essere la risposta corretta, se potesse fare la domanda giusta!
alijunior,

2
Questa sarebbe la risposta corretta, se l'OP chiedesse delle finestre di dialogo ! Ma la domanda riguarda le attività: un caso del tutto diverso.
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.

Guarda questo link per maggiori dettagli su finestra dialogo.

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

Si noti che la domanda riguarda le attività utilizzate come finestre di dialogo, NON la classe Dialog.
Scott Biggs,

8

Semplicemente,

alertDialog.setCancelable(false);

impedire all'utente di fare clic all'esterno della finestra di dialogo.


7

La finestra di avviso è obsoleta, quindi utilizzare la finestra di dialogo = nuova finestra di dialogo (questa);

Per evitare la chiusura al tocco esterno

dialog.setCanceledOnTouchOutside(false);

5

Usa setFinishOnTouchOutside(false)per API> 11 e non ti preoccupare perché il comportamento predefinito di Android per cui la finestra di dialogo a tema attività non verrà completata al tocco esterno per API <11 :) !! Saluti !!


5

Lo uso in onCreate (), sembra funzionare su qualsiasi versione di Android; testato su 5.0 e 4.4.x, impossibile eseguire test su Gingerbread, i dispositivi Samsung (Nota 1 con GB in esecuzione) lo fanno in questo modo per impostazione predefinita:

    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);

Immagino che questo ti aiuterà. Ha funzionato per me


1
Per favore prova anche a spiegare perché questo funzionerà ... Solo un dump del codice non è una buona risposta.
Codebender

3

Ecco la mia soluzione:

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

2

Inoltre è possibile assegnare diverse azioni implementando onCancelListener:

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

Come posso identificare se viene chiamato l'annullamento a causa del tocco all'esterno della finestra di avviso?
cegprakash,

Molto utile per creare azioni personalizzate toccando al di fuori di una finestra di avviso!
Adam S.

1

Stavo affrontando lo stesso problema. Per gestirlo ho impostato OntouchListenera nella finestra di dialogo e non faccio nulla all'interno. Ma la finestra di dialogo viene chiusa anche quando si ruota lo schermo. Per risolverlo ho impostato una variabile per dirmi se la finestra di dialogo è stata normalmente ignorata. Quindi ho impostato a OnDismissListenernella mia finestra di dialogo e all'interno controllo la variabile. Se la finestra di dialogo non è normale normalmente non faccio nulla, altrimenti eseguo di nuovo la finestra di dialogo (e impostando il suo stato come quando disdetto nel mio caso).


1

builder.setCancelable (false);


public void Mensaje (Visualizza 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
Ciao Alex. Benvenuto in StackOverflow e grazie per la tua risposta. Potresti modificare la tua risposta per descrivere cosa fa il tuo codice e come questo risolve il problema del PO? Le risposte al solo codice sono scoraggiate perché non insegnano né spiegano il perché . Grazie!
Tim Malone,

-1

Questa è la risposta perfetta a tutte le tue domande .... Spero ti piaccia la programmazione in 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();

Grazie per questo frammento di codice, che potrebbe fornire un aiuto limitato e immediato. Una spiegazione adeguata migliorerebbe notevolmente il suo valore a lungo termine mostrando perché questa è una buona soluzione al problema e la renderebbe più utile ai futuri lettori con altre domande simili. Modifica la tua risposta per aggiungere alcune spiegazioni, inclusi i presupposti che hai formulato.
Maximilian Peters,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.