Domanda

Ho implementato una finestra di dialogo personalizzata per la mia applicazione. Voglio implementarlo quando l'utente fa clic fuori dalla finestra di dialogo, la finestra di dialogo verrà respinta. Cosa devo fare per questo?

È stato utile?

Soluzione

Puoi usare dialog.setCanceledOnTouchOutside(true); che chiuderà la finestra di dialogo se si tocca al di fuori della finestra di dialogo.

Qualcosa di simile a,

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

O se la tua finestra di dialogo in non modello, allora,

1 - Imposta il flag-FLAG_NOT_TOUCH_MODAL Per l'attributo della finestra del dialogo

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

2 - Aggiungi un altro flag a Windows Properties ,, FLAG_WATCH_OUTSIDE_TOUCH - Questo è per la finestra di dialogo per ricevere un evento touch al di fuori della sua regione visibile.

3 - Override onTouchEvent() di dialogo e verificare il tipo di azione. Se il tipo di azione è 'MotionEvent.ACTION_OUTSIDE'Mezzi, l'utente interagisce al di fuori della regione della finestra di dialogo. Quindi, in questo caso, puoi ridurre la finestra di dialogo o decidere cosa volevi eseguire. Visualizza la plainprint?

public boolean onTouchEvent(MotionEvent event)  
{  

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

Per ulteriori informazioni, guarda Come respingere una finestra di dialogo personalizzata basata sui punti di contatto? eCome respingere la finestra di dialogo non modale, quando toccata la regione della finestra di dialogo

Altri suggerimenti

È possibile utilizzare questa implementazione di Ontouchevent. Impedisce di reagire sotto l'attività all'evento Touch (come detto 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 );
}

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

Semplicemente usa

dialog.setCanceledOnTouchOutside(true);

Oppure, se stai personalizzando la finestra di dialogo usando un tema definito nel tuo stile XML, inserisci questa linea nel tuo tema:

<item name="android:windowCloseOnTouchOutside">true</item>
dialog.setCanceledOnTouchOutside(true); 

Per chiudere il dialogo al tatto fuori.

E se non vuoi chiudere al tatto fuori, usa il codice qui sotto:

dialog.setCanceledOnTouchOutside(false);

Questo metodo dovrebbe evitare completamente le attività al di sotto dell'area grigia recuperando gli eventi.

Rimuovere questa riga se ce l'hai:

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

Mettilo sulla tua attività creata

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

quindi prevalere l'evento touch con questo

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

Puoi provare questo:-

AlterDialog alterdialog;
alertDialog.setCanceledOnTouchOutside(true);

o

alertDialog.setCancelable(true);

E se hai un AlterDialog.Builder Allora puoi provare questo:-

alertDialogBuilder.setCancelable(true);

Questo codice viene utilizzato per quando utilizzare Fare clic su Dialogbox in quel tempo hidesoftinput e quando l'utente fai clic sul lato esterno della finestra di dialogo quel tempo sia softinput che dialogabox sono chiusi.

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

Un'altra soluzione questo codice è stato tagliato dal codice sorgente Android di Window Dovresti semplicemente aggiungere questi due metodi al codice sorgente della finestra di dialogo.

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

Questa soluzione non ha questo problema:

Funziona alla grande tranne per il fatto che l'attività sottostante reagisce anche all'evento Touch. C'è un modo per prevenirlo? - Howettl

Chiamata dialog.setCancelable(false); Dalla tua attività/frammento.

Puoi fare un background Occupando tutte le dimensioni dello schermo transparent e ascolta il onClick evento a dismiss esso.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top