web-dev-qa-db-ja.com

外をタップしてAndroidダイアログを閉じますか?

ポップアップダイアログ(またはダイアログテーマのあるアクティビティ)の外側をどうにかしてタップし、その外側をタップするだけでそれを閉じることができるかどうか疑問に思っていましたか?

私はそれを説明する簡単な写真を作りました:

enter image description here

通常、ダイアログを閉じるにはBackキーを押す必要がありますが、Honeycombでは、すべての画面領域のため、ダイアログの外側をタップするだけのオプションがあると便利です。

37
Michell Bak

私のアプリは、Theme.Holo.Dialogを使用した単一のアクティビティです。私の場合、他の答えはうまくいきませんでした。他のバックグラウンドアプリまたは起動画面のみがタッチイベントを受信するようにしました。

私の場合、 dispatchTouchEvent を使用するとうまくいくことがわかりました。私もそれがより簡単な解決策だと思います。これを使用して、Dialogテーマでアクティビティの外側のタップを検出する方法のサンプルコードを次に示します。

@Override
public boolean dispatchTouchEvent(MotionEvent ev) {
    Rect dialogBounds = new Rect();
    getWindow().getDecorView().getHitRect(dialogBounds);

    if (!dialogBounds.contains((int) ev.getX(), (int) ev.getY())) {
        // Tapped outside so we finish the activity
        this.finish();
    }
    return super.dispatchTouchEvent(ev);
}
47
Jan S.
dialog.setCanceledOnTouchOutside(true) 

ウィンドウの境界の外側をタッチしたときにこのダイアログをキャンセルするかどうかを設定します。

89

ポップアップウィンドウの外側をタッチすると呼び出されるTouchInterceptorメソッドがあります

例えば

_mWindow.setTouchInterceptor(new OnTouchListener() {
            @Override
            public boolean onTouch(View v, MotionEvent event) {
                if (event.getAction() == MotionEvent.ACTION_OUTSIDE) {
                    mWindow.dismiss();

                    return true;
                }

                return false;
            }
        });
_

mWindowはポップアップウィンドウです

また、アクティビティに同じ機能が必要な場合は、以下の手順に従う必要があります。

1)setContentView()で呼び出されるonCreate();メソッドの前にフラグを追加します

_ getWindow().setFlags(LayoutParams.FLAG_NOT_TOUCH_MODAL, LayoutParams.FLAG_NOT_TOUCH_MODAL);

    // ...but notify us that it happened.
    getWindow().setFlags(LayoutParams.FLAG_WATCH_OUTSIDE_TOUCH, LayoutParams.FLAG_WATCH_OUTSIDE_TOUCH);
_

2)アクティビティのonTouchEvent()イベントをオーバーライドする

以下のコードを書きます

_ @Override
        public boolean onTouchEvent(MotionEvent event) {
            if (event.getAction() == MotionEvent.ACTION_OUTSIDE) {
                Toast.makeText(getApplicationContext(), "Finish", 3000).show();
                finish();               
                return true;
            }
            return false;
        }
_

完全なコピーはこちら

アクティビティ

_package net.londatiga.Android;

import Android.app.Activity;
import Android.os.Bundle;

import Android.view.MotionEvent;
import Android.view.View;
import Android.view.View.OnClickListener;
import Android.view.View.OnTouchListener;
import Android.view.WindowManager.LayoutParams;

import Android.widget.Button;
import Android.widget.Toast;

public class NewQuickAction3DActivity extends Activity implements OnTouchListener {

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
         // Make us non-modal, so that others can receive touch events.
        getWindow().setFlags(LayoutParams.FLAG_NOT_TOUCH_MODAL, LayoutParams.FLAG_NOT_TOUCH_MODAL);

        // ...but notify us that it happened.
        getWindow().setFlags(LayoutParams.FLAG_WATCH_OUTSIDE_TOUCH, LayoutParams.FLAG_WATCH_OUTSIDE_TOUCH);

        setContentView(R.layout.main);

    }


    @Override
    public boolean onTouchEvent(MotionEvent event) {
        if (event.getAction() == MotionEvent.ACTION_OUTSIDE) {
            Toast.makeText(getApplicationContext(), "Hi", 3000).show();

            return true;
        }

        return false;
    }
}
_

これはmanifest.xmlです

_<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:Android="http://schemas.Android.com/apk/res/Android"
      package="net.londatiga.Android"
      Android:versionCode="1"
      Android:versionName="1.0">
    <uses-sdk Android:minSdkVersion="7" />

    <application Android:icon="@drawable/icon" Android:label="@string/app_name">
        <activity Android:name=".NewQuickAction3DActivity"
                  Android:label="@string/app_name" Android:theme="@Android:style/Theme.Holo.Dialog">
            <intent-filter>
                <action Android:name="Android.intent.action.MAIN" />
                <category Android:name="Android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>

    </application>
</manifest>
_
14
Dharmendra

ダイアログがActivityの場合、 Activity#setFinishOnTouchOutside も使用できます。それはActivitysの最短の方法になります;)

(ただし、API 11+です。ただし、API <= 10は通常、通常の画面サイズです。)

5
nmr

使用してもよい

  dialog.setCancelable(true\false); 

Androidの最新バージョンの場合。

OutSide Touchingイベントを無効にします。

5
Amt87

Dialog.setCanceledOnTouchOutside(false);と書くだけです。そしてそれは私のために働いて、窓は外側のタップで消えません。

4
    dialog = new Dialog(MainActivity.this);
    dialog.requestWindowFeature(Window.FEATURE_NO_TITLE);
    dialog.setContentView(R.layout.dialog_layout);
    dialog.getWindow().setBackgroundDrawableResource(
            Android.R.color.transparent);
    dialog.setCancelable(false);

    dialog.setCanceledOnTouchOutside(true);

このコード行があるかどうかを確認してください。..

    dialog.setCanceledOnTouchOutside(true);
3
Manoj Behera

他のスタイルではなくダイアログのスタイルを使用します。

たとえば、使用

public YourCustomDialog(Context context) {
    super(context, Android.R.style.Theme_Holo_dialog_NoActionBar);
}

Theme_Translucent_NoTitleBarなどの他のスタイルを使用する場合、ダイアログは閉じられません。

1
Mark

this.setFinishOnTouchOutside(false);

これを使用できます

1
Gopi Cg

古い質問ですが、さらに別の解決策:

  1. 前景アクティビティをフルスクリーンにします。ネストされたレイアウト:フルスクリーンレイアウトには透明な背景が必要です(例:_@null_または_@Android:color/transparent_)。内部レイアウトには背景が表示されている必要があります。

  2. アクティビティをfinish() esする非表示の外部レイアウトにOnClickListenerを追加します。

1
laalto

ダイアログ内のすべてのビューは、以下が呼び出されないように、タッチイベントを消費するように設定できます。

onCreate(){
    getWindow().getDecorView().getRootView().setOnTouchListener(new OnTouchListener(){
        @Override
        public boolean onTouch(View v, MotionEvent event) {
            dialog.dismiss();
            return false;
        }
    });
0
jungwhan cho
LayoutParams lp=dialogp.getWindow().getAttributes(); 
lp.flags=LayoutParams.FLAG_LAYOUT_NO_LIMITS;

これを追加し、3.0までは問題なく動作しますが、すべてで動作するはずです。

0
a54studio