ダイアログの外側をクリックしてダイアログを閉じる方法は?


回答:


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 2012年

うん。window.setFlags(WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL、WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL); この問題が発生します。私は以下の解決策を投稿しました:)
Unknownweirdo 2014年

非カスタムダイアログを使用して、「on-touch-outside」イベントを下のアクティビティに伝播することは可能ですか?
jc

1
@howettl ウィンドウにフラグを設定する必要がない、以下投稿した私のソリューション問題を解決しました。
ローマナザレビッチ2014

@MuhammedRefaat-このスレッドgroups.google.com/forum/#!topic/android-developers/VhaiIMl6E_wをご覧ください。彼らはそれをうまく説明しました。
user370305 2014年

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 2014年

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

このコードは、ダイアログボックスで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;
    }
};

2

別の解決策、このコードはAndroidのソースコードから取得したWindow ものです。これらの2つのメソッドをダイアログのソースコードに追加するだけです。

@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 14

-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.