170

アプリケーションにカスタム ダイアログを実装しました。ユーザーがダイアログの外側をクリックすると、ダイアログが閉じられるように実装したいと思います。これには何をしなければなりませんか?

4

14 に答える 14

378

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 - ウィンドウ プロパティに別のフラグを追加します。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;  
}  

詳細については、タッチ ポイントに基づいてカスタム ダイアログを閉じる方法を参照してください。ダイアログ領域の外に触れたときに非モーダルダイアログを閉じる方法

于 2011-12-05T10:47:02.060 に答える
21

単に使用する

dialog.setCanceledOnTouchOutside(true);
于 2013-06-18T11:19:21.703 に答える
17

この 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/clothing-activity-by-touching-outside.html

于 2012-03-30T22:08:09.843 に答える
9

または、スタイル xml で定義されたテーマを使用してダイアログをカスタマイズしている場合は、次の行をテーマに追加します。

<item name="android:windowCloseOnTouchOutside">true</item>
于 2013-07-30T09:18:00.760 に答える
8
dialog.setCanceledOnTouchOutside(true); 

外側に触れるとダイアログを閉じます。

また、外に触れても閉じたくない場合は、以下のコードを使用してください。

dialog.setCanceledOnTouchOutside(false);
于 2014-07-13T15:04:19.083 に答える
6

これを試すことができます:-

AlterDialog alterdialog;
alertDialog.setCanceledOnTouchOutside(true);

また

alertDialog.setCancelable(true);

そして、あなたが持っているなら、あなたはAlterDialog.Builderこれを試すことができます:-

alertDialogBuilder.setCancelable(true);
于 2016-12-27T10:31:25.877 に答える
5

このコードは、hidesoftinput のときにダイアログ ボックスをクリックして使用する場合、およびユーザーがソフト入力とダイアログ ボックスの両方が閉じているときにダイアログ ボックスの外側をクリックする場合に使用されます。

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;
    }
};
于 2015-12-22T06:19:04.567 に答える
3

別の解決策として、このコードは 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));
}

このソリューションには、この問題はありません:

これは、下のアクティビティもタッチイベントに反応することを除けば、うまく機能します。これを防ぐ方法はありますか?–ハウトル

于 2014-07-07T13:54:57.727 に答える
2

以下は私のために働いた:

myDialog.setCanceledOnTouchOutside(true);
于 2019-12-05T08:56:59.187 に答える
0

background画面全体を占めるを作成し、それに対してイベントをtransparent聞くことができます。onClickdismiss

于 2011-12-05T10:45:05.250 に答える