대화 상자 외부를 클릭하여 대화 상자를 닫는 방법은 무엇입니까?


답변:


356

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'인 경우 사용자는 대화 상자 영역 외부에서 상호 작용하고 있습니다. 따라서이 경우 대화 상자를 닫거나 수행하려는 작업을 결정할 수 있습니다. 지문을 보시겠습니까?

public boolean onTouchEvent(MotionEvent event)  
{  

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

자세한 내용 은 터치 포인트를 기반으로 사용자 정의 대화 상자 를 해제 하는 방법을 참조하십시오 . 그리고 이 아닌 모달 대화 상자를 닫으려면 어떻게 외부의 대화 영역을 만졌을 때


9
아래의 활동이 터치 이벤트에 반응한다는 점을 제외하고는 효과적입니다. 이것을 막을 방법이 있습니까?
howettl

네. window.setFlags (WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL, WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL); 이 문제가 발생합니다. 나는 아래에 해결책을 게시했다 :)
Unknownweirdo

사용자 지정이 아닌 대화 상자를 사용하여 'on-touch-outside'이벤트를 아래 활동으로 전파 할 수 있습니까?
jc

1
@ howettl 나는 깃발을 창에 설정할 필요가없는 아래게시 한 내 솔루션에서 문제를 해결했습니다 .
로마 나자 레 비치

@MuhammedRefaat-이 스레드 groups.google.com/forum/#!topic/android-developers/VhaiIMl6E_w를 참조하십시오 . 그들은 잘 설명했다.
user370305

18

간단히 사용

dialog.setCanceledOnTouchOutside(true);

나는 이것이 정답이어야한다는 것을 알고 있지만 나에게는 효과가 없으며 그 이유를 모른다.
IgniteCoders

16

이 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


9

또는 스타일 xml에 정의 된 테마를 사용하여 대화 상자를 사용자 정의하는 경우 다음 행을 테마에 넣으십시오.

<item name="android:windowCloseOnTouchOutside">true</item>

Samsung Galaxy Tab 2 WiFi에서는 작동하지 않습니다. dialog.setCanceledOnTouchOutside(true);훌륭하게 작동합니다.
doplumi

7
dialog.setCanceledOnTouchOutside(true); 

외부 터치시 대화 상자를 닫습니다.

외부에서 직접 터치하지 않으려면 아래 코드를 사용하십시오.

dialog.setCanceledOnTouchOutside(false);

6

이 방법은 클릭 이벤트를 검색하는 회색 영역 아래의 활동을 완전히 피해야합니다.

이 줄이 있으면 제거하십시오 .

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

4

당신은 이것을 시도 할 수 있습니다 :-

AlterDialog alterdialog;
alertDialog.setCanceledOnTouchOutside(true);

또는

alertDialog.setCancelable(true);

그리고 당신이 있다면 AlterDialog.Builder다음을 시도 할 수 있습니다 :-

alertDialogBuilder.setCancelable(true);

4

이 코드는 softsoftput을 숨길 때 대화 상자를 클릭 할 때와 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;
    }
};

2

또 다른 해결책,이 코드는 안드로이드 소스 코드에서 가져온 것입니다. 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


다른 창에서 이벤트를 수신하지 않으려면 대화 상자를 모달로 만듭니 까?

1

dialog.setCancelable(false);활동 / 조각에서 전화 하십시오.



0

당신은 할 수 있습니다 background점령 모든 화면 크기 transparent와 청취 onClick에 이벤트 dismiss그것.


10
아주 나쁜 대답입니다! 물론이 작업을 수행 할 수 있지만 올바른 방법으로 수행하십시오!
jc

-1

여기 코드가 있습니다

    dialog.getWindow().getDecorView().setOnTouchListener(new View.OnTouchListener() {
        @Override
        public boolean onTouch(View v, MotionEvent ev) {

            if(MotionEvent.ACTION_DOWN == ev.getAction())
            {
                Rect dialogBounds = new Rect();
                dialog. getWindow().getDecorView().getHitRect(dialogBounds);
                if (!dialogBounds.contains((int) ev.getX(), (int) ev.getY())) {
                    // You have clicked the grey area
                    UiUtils.hideKeyboard2(getActivity());
                    return false; // stop activity closing
                }
            }
            getActivity().dispatchTouchEvent(ev);
            return false;
        }
    });

이거 한번 해봐 . 외부를 만질 때 키보드를 숨길 수 있습니다

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.