Empêcher la boîte de dialogue d'activité Android de se fermer sur une touche extérieure


229

J'ai une activité qui utilise le style Theme.Dialog de telle sorte que c'est une fenêtre flottante sur une autre activité. Cependant, lorsque je clique en dehors de la fenêtre de dialogue (sur l'activité d'arrière-plan), la boîte de dialogue se ferme. Comment puis-je arrêter ce comportement?


1
Pourquoi feriez-vous cela btw. SI le comportement souhaité est celui d'une boîte de dialogue, pourquoi ne pas utiliser une boîte de dialogue? Pour en venir à votre question, je ne pense pas qu'il y ait de solution à cela.
Kumar Bibek

Les boîtes de dialogue @KumarBibek sont limitées en ce qui concerne les personnalisations de mise en page ... c'est pourquoi une activité. Même le développeur docs recommande cette approche pour une personnalisation flexible
Leo

1
Et ce que l'OP veut , c'est une boîte de dialogue modale , c'est-à-dire une boîte de dialogue qui oblige l'utilisateur à répondre, comme OK ou Oui / Non. L'utilisateur ne doit pas pouvoir cliquer simplement.
Scott Biggs

Réponses:


34

Cela pourrait vous aider. C'est un moyen de gérer l'événement tactile extérieur:

Comment annuler une activité sur le thème du dialogue comme lorsque vous touchez à l'extérieur de la fenêtre?

En saisissant l'événement et en ne faisant rien, je pense que vous pouvez empêcher la fermeture. Mais ce qui est étrange, c'est que le comportement par défaut de votre boîte de dialogue d'activité ne doit pas se fermer lorsque vous touchez l'extérieur.

(PS: le code utilise WindowManager.LayoutParams)


1
L'objet n'est pas une boîte de dialogue, c'est une activité qui utilise le style de boîte de dialogue. L'activité n'a pas cette méthode et ne peut pas être convertie en boîte de dialogue.
Fergusmac

Notre message est exactement le contraire de ce qui a été demandé. il a demandé comment empêcher la fermeture et non comment la provoquer.
ChuckKelly

4
C'est ce qu'il a expliqué avec "En saisissant l'événement et en ne faisant rien, je pense que vous pouvez empêcher la clôture".
metter

4
pour une raison quelconque, après avoir fait tout FLAG_NOT_MODAL, WATCH_OUTSIDE_TOUCH, la touche extérieure ne fait pas fermer les activités, mais le bouton derrière l'activité est cliqué. une idée pour ça?
njzk2

Notez que les boîtes de dialogue ont une ombre (au moins jusqu'à présent (8.0)): si vous cliquez sur l'ombre, Android interprètera ce clic comme s'il était à l'intérieur de la boîte de dialogue. Je voulais juste partager cela avec le monde, il m'a fallu 10 minutes pour l'obtenir.
Lorenzo Von Matterhorn

459

Pour éviter que la boîte de dialogue ne soit fermée lorsque vous appuyez sur la touche Retour, utilisez cette

dialog.setCancelable(false);

Et pour éviter que la boîte de dialogue ne soit fermée sur une touche extérieure, utilisez cette

 dialog.setCanceledOnTouchOutside(false);

4
Cette réponse est utile mais cette question concerne l'activité utilisant l'attribut Theme.Dialog.
Paresh Mayani

15
Je sais quand je me rends compte qu'il est trop tard car cela aide beaucoup de gens donc je ne l'ai pas supprimé.
Singhak

12
Je sais que cela ne concernait pas vraiment la question, mais cela m'a aidé. Merci!
dennisdrew

5
C'est la meilleure réponse. Je soupçonne que la plupart des personnes qui trouvent cette question recherchent un moyen d'empêcher la norme AlertDialogde se fermer au toucher à l'extérieur, et c'est ce que cette réponse fournit.
aroth

20
Sur les nouvelles versions d'AlertDialog, il vous suffit d'utilisersetCancelable(false)
Kobi Tate

120

Ce que vous avez réellement est une activité (même si elle ressemble à une boîte de dialogue), vous devez donc appeler setFinishOnTouchOutside(false)depuis votre activité si vous souhaitez la garder ouverte lorsque vous cliquez sur l'activité en arrière-plan.

EDIT: Cela ne fonctionne qu'avec l'API Android de niveau 11 ou supérieur


4
Cela ne vous empêche pas d'appuyer sur le bouton "retour" dans votre activité. Donc, vous devez également passer outre à onBackPressed()ne rien faire dans son corps
Alex Bonel

Il n'empêche pas le bouton "retour" dans cette boîte de dialogue Activité sans onBackPressed (). Fonctionne parfaitement avec this.setFinishOnTouchOutside (false).
Kunalxigxag

68

Ce qui a fonctionné pour moi, c'est de créer DialogFragmentun ensemble pour qu'il ne soit pas annulable:

dialog.setCancelable(false);

1
Inutile. Cette question concerne les activités, pas les dialogues.
Scott Biggs

20

Lors de l'utilisation de la boîte de dialogue en tant qu'activité dans onCreate, ajoutez ceci

setFinishOnTouchOutside(false);

17

Pour l'API 10 supérieure, la boîte de dialogue disparaît lorsqu'elle est touchée à l'extérieur, tandis que dans une version inférieure à l'API 11, la boîte de dialogue ne disparaît pas. Pour éviter cela, vous devez faire:

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

OU

Dans la onCreate()méthode, utilisez:this.setFinishOnTouchOutside(false);

Remarque: pour l'API 10 et les versions antérieures, cette méthode n'a aucun effet et n'est pas nécessaire.


14

La définition de la boîte de dialogue annulable sur false est suffisante, et soit vous touchez en dehors de la boîte de dialogue d'alerte, soit vous cliquez sur le bouton Précédent pour faire disparaître la boîte de dialogue d'alerte. Alors utilisez celui-ci:

setCancelable(false)

Et l'autre fonction n'est plus nécessaire: dialog.setCanceledOnTouchOutside(false);

Si vous créez une boîte de dialogue temporaire et que vous vous demandez où mettre cette ligne de code, voici un exemple:

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

Utilisez ce code, ça marche pour moi

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


ce devrait être la bonne réponse, s'il pouvait faire la bonne question!
alijunior

2
Ce serait la bonne réponse, si le PO demandait des dialogues ! Mais la question concerne les activités - un tout autre cas.
Scott Biggs du

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.

Regardez ce lien pour plus de détails sur la boîte de dialogue.

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

Veuillez noter que la question concerne les activités utilisées comme dialogues, PAS la classe Dialog.
Scott Biggs

8

Simplement,

alertDialog.setCancelable(false);

empêcher l'utilisateur de cliquer en dehors de la boîte de dialogue.


7

La boîte de dialogue d'alerte est obsolète, utilisez donc Dialogue dialog = new Dialog (this);

Pour empêcher le contact avec l'extérieur

dialog.setCanceledOnTouchOutside(false);

5

Utilisez setFinishOnTouchOutside(false)pour API> 11 et ne vous inquiétez pas, car le comportement par défaut de son androïde que la boîte de dialogue sur le thème de l'activité ne sera pas terminé sur une touche extérieure pour API <11 :) !!


5

J'utilise ceci dans onCreate (), semble fonctionner sur n'importe quelle version d'Android; testé sur 5.0 et 4.4.x, ne peut pas tester sur Gingerbread, les appareils Samsung (Note 1 exécutant Go) l'ont de cette façon par défaut:

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

Je suppose que cela vous aidera.


1
Essayez également d'expliquer pourquoi cela fonctionnera ... Un simple vidage de code n'est pas une bonne réponse.
Codebender

3

Voici ma solution:

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

2

Il est également possible d'affecter différentes actions implémentant onCancelListener:

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

Comment savoir si l'annulation est appelée en raison d'un tapotement en dehors de la boîte de dialogue d'alerte?
cegprakash

Très utile pour créer des actions personnalisées en tapant en dehors d'une boîte de dialogue d'alerte!
Adam S.

1

J'étais confronté au même problème. Pour le gérer, j'ai mis un OntouchListenerdans la boîte de dialogue et je ne fais rien à l'intérieur. Mais la boîte de dialogue disparaît également lors de la rotation de l'écran. Pour le corriger, j'ai défini une variable pour me dire si la boîte de dialogue s'est normalement fermée. Ensuite, je mets un OnDismissListenerà ma boîte de dialogue et à l'intérieur je vérifie la variable. Si la boîte de dialogue n'a pas disparu normalement, je ne fais rien, ou bien je lance à nouveau la boîte de dialogue (et en définissant son état comme lors du rejet dans mon cas).


1

builder.setCancelable (false);


public nul Mensaje (vue 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
Salut Alex. Bienvenue sur StackOverflow et merci pour votre réponse. Pourriez-vous modifier votre réponse pour décrire ce que fait votre code et comment cela résout le problème de l'OP? Les réponses codées uniquement sont découragées car elles n'enseignent pas et n'expliquent pas pourquoi . Je vous remercie!
Tim Malone

-1

Ceci est la réponse parfaite à toutes vos questions .... J'espère que vous apprécierez le codage dans 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();

Merci pour cet extrait de code, qui pourrait fournir une aide limitée et immédiate. Une explication appropriée améliorerait considérablement sa valeur à long terme en montrant pourquoi il s'agit d'une bonne solution au problème et le rendrait plus utile aux futurs lecteurs ayant d'autres questions similaires. Veuillez modifier votre réponse pour ajouter des explications, y compris les hypothèses que vous avez faites.
Maximilian Peters
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.