Как закрыть диалоговое окно с щелчком на вне диалога?


я реализовал пользовательский диалог для моего приложения. Я хочу реализовать это, когда пользователь нажимает вне диалогового окна, диалог будет отклонен. Что я должен сделать для этого?

11 133

11 ответов:

можно использовать dialog.setCanceledOnTouchOutside(true); который закроет диалоговое окно, если вы коснетесь за пределами диалогового окна.

что-то вроде

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

или если ваш диалог в не-модели, то,

1-установите флаг -FLAG_NOT_TOUCH_MODAL для атрибута окна вашего диалога

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

2-добавить еще один флаг в свойства windows,,FLAG_WATCH_OUTSIDE_TOUCH - Это один для диалога, чтобы получить сенсорное событие за пределами его видимой области.

3 - переопределение onTouchEvent() диалога и проверить действие тип. если тип действия - MotionEvent.ACTION_OUTSIDE' означает, что пользователь взаимодействует вне диалогового области. Таким образом, в этом случае вы можете dimiss свой диалог или решить, что вы хотели выполнить. посмотреть plainprint?

public boolean onTouchEvent(MotionEvent event)  
{  

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

для получения дополнительной информации смотрите на как закрыть пользовательский диалог на основе точек касания? и как закрыть ваш немодальный диалог, при прикосновении вне области диалога

вы можете использовать эту реализацию onTouchEvent. Он предотвращает от реагировать под деятельностью к событию касания (как упомянуто 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 );
}

Источник:http://blog.twimager.com/2010/08/closing-activity-by-touching-outside.html

просто использовать

dialog.setCanceledOnTouchOutside(true);

или, если вы настраиваете диалог, используя тему, определенную в вашем стиле xml, поместите эту строку в свою тему:

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

закрыть диалог на ощупь снаружи.

и если вы не хотите, чтобы закрыть на ощупь снаружи, используйте код ниже:

dialog.setCanceledOnTouchOutside(false);

этот метод должен полностью избегать действий под серой областью, извлекая события щелчка.

удалить эта строка, если она у вас есть:

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

положите это на вашу деятельность, созданную

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

затем переопределите событие касания с помощью этого

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

вы можете попробовать это :-

AlterDialog alterdialog;
alertDialog.setCanceledOnTouchOutside(true);

или

alertDialog.setCancelable(true);

и если у вас есть AlterDialog.Builder затем вы можете попробовать это:-

alertDialogBuilder.setCancelable(true);

другое решение этот код был вырезан из исходного кода android Window Вы должны просто добавить эти два метода диалогового кода.

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

это решение не имеет этой проблемы :

это отлично работает, за исключением того, что активность внизу также реагирует на событие касания. Есть ли способ предотвратить это? - howettl

этот код используется при использовании нажмите на диалоговое окно, что время hidesoftinput и когда пользователь нажмите внешнюю сторону диалогового окна, что время и softinput и диалоговое окно близки.

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

можно сделать background занимая весь размер экрана transparent и слушать onClick событие dismiss его.

вызов dialog.setCancelable(false); от вашей деятельности/фрагмент.