web-dev-qa-db-fra.com

Appuyez en dehors de la boîte de dialogue Android pour la rejeter?

Je me demandais s'il était possible de cliquer d'une manière ou d'une autre en dehors d'une boîte de dialogue contextuelle (ou d'une activité avec un thème de boîte de dialogue) et de la rejeter en appuyant simplement en dehors de celle-ci?

J'ai fait une photo rapide pour l'illustrer:

enter image description here

Normalement, vous devez appuyer sur la touche Retour pour fermer les boîtes de dialogue, mais sous Honeycomb, il pourrait être intéressant de pouvoir taper en dehors de la boîte de dialogue, en raison de la totalité de l'écran.

37
Michell Bak

Mon application est une activité unique avec Theme.Holo.Dialog. Dans mon cas, l'autre réponse n'a pas fonctionné. Seules les autres applications d'arrière-plan ou l'écran de lancement étaient conçues pour recevoir des événements tactiles.

J'ai trouvé que l'utilisation de dispatchTouchEvent fonctionne dans mon cas. Je pense que c'est aussi une solution plus simple. Voici un exemple de code sur la façon de l'utiliser pour détecter des taps en dehors de l'activité avec un thème de dialogue:

@Override
public boolean dispatchTouchEvent(MotionEvent ev) {
    Rect dialogBounds = new Rect();
    getWindow().getDecorView().getHitRect(dialogBounds);

    if (!dialogBounds.contains((int) ev.getX(), (int) ev.getY())) {
        // Tapped outside so we finish the activity
        this.finish();
    }
    return super.dispatchTouchEvent(ev);
}
47
Jan S.
dialog.setCanceledOnTouchOutside(true) 

Définit si cette boîte de dialogue est annulée lorsque touché en dehors des limites de la fenêtre.

89
Francesco Vadicamo

Il existe une méthode TouchInterceptor qui sera appelée lorsque vous toucherez du côté extérieur de la fenêtre contextuelle.

Par exemple 

mWindow.setTouchInterceptor(new OnTouchListener() {
            @Override
            public boolean onTouch(View v, MotionEvent event) {
                if (event.getAction() == MotionEvent.ACTION_OUTSIDE) {
                    mWindow.dismiss();

                    return true;
                }

                return false;
            }
        });

mWindow est la fenêtre popup

Et si vous voulez la même fonctionnalité pour l'activité, vous devez suivre les étapes ci-dessous.

1) Ajouter un indicateur avant la méthode setContentView() appelée dans onCreate();

 getWindow().setFlags(LayoutParams.FLAG_NOT_TOUCH_MODAL, LayoutParams.FLAG_NOT_TOUCH_MODAL);

    // ...but notify us that it happened.
    getWindow().setFlags(LayoutParams.FLAG_WATCH_OUTSIDE_TOUCH, LayoutParams.FLAG_WATCH_OUTSIDE_TOUCH);

2) Remplacer l'événement onTouchEvent() dans l'activité

et écrivez ci-dessous le code

 @Override
        public boolean onTouchEvent(MotionEvent event) {
            if (event.getAction() == MotionEvent.ACTION_OUTSIDE) {
                Toast.makeText(getApplicationContext(), "Finish", 3000).show();
                finish();               
                return true;
            }
            return false;
        }

La copie complète est ici

Activité

package net.londatiga.Android;

import Android.app.Activity;
import Android.os.Bundle;

import Android.view.MotionEvent;
import Android.view.View;
import Android.view.View.OnClickListener;
import Android.view.View.OnTouchListener;
import Android.view.WindowManager.LayoutParams;

import Android.widget.Button;
import Android.widget.Toast;

public class NewQuickAction3DActivity extends Activity implements OnTouchListener {

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
         // Make us non-modal, so that others can receive touch events.
        getWindow().setFlags(LayoutParams.FLAG_NOT_TOUCH_MODAL, LayoutParams.FLAG_NOT_TOUCH_MODAL);

        // ...but notify us that it happened.
        getWindow().setFlags(LayoutParams.FLAG_WATCH_OUTSIDE_TOUCH, LayoutParams.FLAG_WATCH_OUTSIDE_TOUCH);

        setContentView(R.layout.main);

    }


    @Override
    public boolean onTouchEvent(MotionEvent event) {
        if (event.getAction() == MotionEvent.ACTION_OUTSIDE) {
            Toast.makeText(getApplicationContext(), "Hi", 3000).show();

            return true;
        }

        return false;
    }
}

Ceci est manifest.xml

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:Android="http://schemas.Android.com/apk/res/Android"
      package="net.londatiga.Android"
      Android:versionCode="1"
      Android:versionName="1.0">
    <uses-sdk Android:minSdkVersion="7" />

    <application Android:icon="@drawable/icon" Android:label="@string/app_name">
        <activity Android:name=".NewQuickAction3DActivity"
                  Android:label="@string/app_name" Android:theme="@Android:style/Theme.Holo.Dialog">
            <intent-filter>
                <action Android:name="Android.intent.action.MAIN" />
                <category Android:name="Android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>

    </application>
</manifest>
14
Dharmendra

Vous pouvez utiliser Activity # setFinishOnTouchOutside aussi, si votre boîte de dialogue est une Activity. Ce doit être le moyen le plus court pour Activitys;)

(C'est l'API 11+ cependant. Mais l'API <= 10 est généralement de taille d'écran normale.)

5
nmr

Vous pouvez utiliser 

  dialog.setCancelable(true\false); 

Pour les dernières versions d'Android; 

Cela désactivera l'événement OutSide Touch.

5
Amt87

J'écris simplement dialog.setCanceledOnTouchOutside (false); et ça marche pour moi, la fenêtre ne sera pas fermée au robinet extérieur.

4
Sachindra N. Pandey
    dialog = new Dialog(MainActivity.this);
    dialog.requestWindowFeature(Window.FEATURE_NO_TITLE);
    dialog.setContentView(R.layout.dialog_layout);
    dialog.getWindow().setBackgroundDrawableResource(
            Android.R.color.transparent);
    dialog.setCancelable(false);

    dialog.setCanceledOnTouchOutside(true);

Vérifiez si vous avez cette ligne de code ou non ....

    dialog.setCanceledOnTouchOutside(true);
3
Manoj Behera

Utilisez un style de dialogue plutôt que d'autres styles.

Par exemple, utiliser

public YourCustomDialog(Context context) {
    super(context, Android.R.style.Theme_Holo_dialog_NoActionBar);
}

Lorsque vous utilisez d'autres styles tels que Theme_Translucent_NoTitleBar , la boîte de dialogue ne sera pas fermée.

1
Mark

this.setFinishOnTouchOutside (false);

tu peux utiliser ça

1
Gopi Cg

Ancienne question mais encore une autre solution:

  1. Faites votre activité de premier plan en plein écran. Mises en page utilisées: La mise en page plein écran doit avoir un fond transparent (par exemple, @null ou @Android:color/transparent). La disposition interne doit avoir un arrière-plan visible.

  2. Ajoutez une OnClickListener à la présentation externe invisible qui finish()es votre activité.

1
laalto

Toutes les vues de la boîte de dialogue peuvent être configurées pour utiliser l'événement tactile afin que l'appel ci-dessous ne soit pas appelé.

onCreate(){
    getWindow().getDecorView().getRootView().setOnTouchListener(new OnTouchListener(){
        @Override
        public boolean onTouch(View v, MotionEvent event) {
            dialog.dismiss();
            return false;
        }
    });
0
jungwhan cho
LayoutParams lp=dialogp.getWindow().getAttributes(); 
lp.flags=LayoutParams.FLAG_LAYOUT_NO_LIMITS;

J'ai ajouté ceci et cela fonctionne parfaitement sur la version 3.0, mais devrait fonctionner sur tous.

0
a54studio