Comment rejeter la boîte de dialogue en cliquant sur en dehors de la boîte de dialogue?

j'ai implémenté un dialogue personnalisé pour mon application. Je tiens à mettre en œuvre que lorsque l'utilisateur clique en dehors de la boîte de dialogue, celle-ci sera rejetée. Que dois-je faire pour cela?

133
demandé sur tvkanters 2011-12-05 14:42:08

11 réponses

vous pouvez utiliser dialog.setCanceledOnTouchOutside(true); qui fermera le dialogue si vous touchez en dehors du dialogue.

quelque chose comme,

  Dialog dialog = new Dialog(context)
  dialog.setCanceledOnTouchOutside(true);

Ou si votre boîte de Dialogue non-modèle, puis,

1 - Mettez le drapeau - FLAG_NOT_TOUCH_MODAL pour l'attribut de fenêtre de votre dialogue

Window window = this.getWindow();
window.setFlags(WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL,
WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL);

2-Ajouter un autre drapeau aux propriétés de windows, FLAG_WATCH_OUTSIDE_TOUCH - celui-ci est pour que dialog reçoive l'événement touch en dehors de sa région visible.

3 - Remplacer onTouchEvent() de dialogue et de vérifier par type d'action. si le type d'action est ' MotionEvent.ACTION_OUTSIDE ' signifie que l'utilisateur interagit en dehors de la zone de dialogue. Ainsi, dans ce cas, vous pouvez diminuer votre dialogue ou décider ce que vous vouliez effectuer. vue plainprint?

public boolean onTouchEvent(MotionEvent event)  
{  

       if(event.getAction() == MotionEvent.ACTION_OUTSIDE){  
        System.out.println("TOuch outside the dialog ******************** ");  
               this.dismiss();  
       }  
       return false;  
}  

pour plus d'informations regardez comment rejeter un dialogue personnalisé basé sur des points de contact? et comment rejeter votre dialogue non-modal, quand touché à l'extérieur de la zone de dialogue

319
répondu user370305 2011-12-05 10:52:12

vous pouvez utiliser cette implémentation de onTouchEvent. Il empêche de réagir en dessous de l'activité à l'événement de toucher (comme mentionné howettl).

@Override
public boolean onTouchEvent ( MotionEvent event ) {
  // I only care if the event is an UP action
  if ( event.getAction () == MotionEvent.ACTION_UP ) {
    // create a rect for storing the window rect
    Rect r = new Rect ( 0, 0, 0, 0 );
    // retrieve the windows rect
    this.getWindow ().getDecorView ().getHitRect ( r );
    // check if the event position is inside the window rect
    boolean intersects = r.contains ( (int) event.getX (), (int) event.getY () );
    // if the event is not inside then we can close the activity
    if ( !intersects ) {
      // close the activity
      this.finish ();
      // notify that we consumed this event
      return true;
    }
  }
  // let the system handle the event
  return super.onTouchEvent ( event );
}

Source: http://blog.twimager.com/2010/08/closing-activity-by-touching-outside.html

16
répondu Lukas Novak 2012-03-30 22:08:09

utilisation simple

dialog.setCanceledOnTouchOutside(true);
14
répondu Ebin Sebastian 2013-06-18 11:19:21

ou, si vous personnalisez la boîte de dialogue en utilisant un thème défini dans votre style xml, mettez cette ligne dans votre thème:

<item name="android:windowCloseOnTouchOutside">true</item>
8
répondu Chris.Zou 2013-07-30 09:18:00
dialog.setCanceledOnTouchOutside(true); 

pour fermer le dialogue sur le toucher extérieur.

et si vous ne voulez pas fermer à l'extérieur, utilisez le code ci-dessous:

dialog.setCanceledOnTouchOutside(false);
6
répondu Naveen 2018-07-03 03:24:41

cette méthode devrait éviter complètement les activités sous les événements de clic de récupération de zone grise.

Supprimer cette ligne si vous l'avez:

window.setFlags(WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL, WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL);

mettez ceci sur votre activité créée

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

puis annuler l'événement tactile avec ce

@Override
public boolean onTouchEvent(MotionEvent ev)
{
    if(MotionEvent.ACTION_DOWN == ev.getAction())
    {
        Rect dialogBounds = new Rect();
        getWindow().getDecorView().getHitRect(dialogBounds);
        if (!dialogBounds.contains((int) ev.getX(), (int) ev.getY())) {
            // You have clicked the grey area
            displayYourDialog();
            return false; // stop activity closing
        }
    }

    // Touch events inside are fine.
    return super.onTouchEvent(ev);
}
5
répondu Unknownweirdo 2014-06-26 16:06:46

vous pouvez essayer ceci: -

AlterDialog alterdialog;
alertDialog.setCanceledOnTouchOutside(true);

ou

alertDialog.setCancelable(true);

Et si vous avez un AlterDialog.Builder , Alors vous pouvez essayer ceci:-

alertDialogBuilder.setCancelable(true);
4
répondu Mohammad Julfikar 2016-12-27 10:31:25

une autre solution ce code a été découpé à partir du code source android de Window Vous devez juste ajouter ces deux méthodes à votre code source de dialogue.

@Override
public boolean onTouchEvent(MotionEvent event) {        
    if (isShowing() && (event.getAction() == MotionEvent.ACTION_DOWN
            && isOutOfBounds(getContext(), event) && getWindow().peekDecorView() != null)) {
        hide();
    }
    return false;
}

private boolean isOutOfBounds(Context context, MotionEvent event) {
    final int x = (int) event.getX();
    final int y = (int) event.getY();
    final int slop = ViewConfiguration.get(context).getScaledWindowTouchSlop();
    final View decorView = getWindow().getDecorView();
    return (x < -slop) || (y < -slop)
            || (x > (decorView.getWidth()+slop))
            || (y > (decorView.getHeight()+slop));
}

Cette solution n'a pas ce problème:

Cela fonctionne très bien, sauf que l'activité sous réagit également à l'événement tactile. Est-il un moyen pour éviter cela? - howettl 151930920"

2
répondu Lemberg 2014-07-07 13:54:57

ce code est utilisé pour quand l'utilisation cliquer sur boîte de dialogue que le temps hidesoftinput et quand l'utilisateur cliquer côté extérieur de boîte de dialogue que le temps softinput et boîte de dialogue sont proches.

dialog = new Dialog(act) {
    @Override
    public boolean onTouchEvent(MotionEvent event) {
        // Tap anywhere to close dialog.
        Rect dialogBounds = new Rect();
        getWindow().getDecorView().getHitRect(dialogBounds);
        if (!dialogBounds.contains((int) event.getX(),
                (int) event.getY())) {
            // You have clicked the grey area
            InputMethodManager inputMethodManager = (InputMethodManager) act
                    .getSystemService(act.INPUT_METHOD_SERVICE);
            inputMethodManager.hideSoftInputFromWindow(dialog
                    .getCurrentFocus().getWindowToken(), 0);
            dialog.dismiss();
            // stop activity closing
        } else {
            InputMethodManager inputMethodManager = (InputMethodManager) act
                    .getSystemService(act.INPUT_METHOD_SERVICE);
            inputMethodManager.hideSoftInputFromWindow(dialog
                    .getCurrentFocus().getWindowToken(), 0);
        }

        return true;
    }
};
2
répondu Maulik Santoki 2018-07-03 03:26:41

vous pouvez faire un background occupant toute la taille de l'écran transparent et écouter l'événement onClick à dismiss il.

0
répondu oriolpons 2014-04-10 03:42:46

Appel dialog.setCancelable(false); à partir de votre activité/fragment.

0
répondu EKN 2018-07-03 03:27:07