ポップアップダイアログ(またはダイアログテーマのあるアクティビティ)の外側をどうにかしてタップし、その外側をタップするだけでそれを閉じることができるかどうか疑問に思っていましたか?
私はそれを説明する簡単な写真を作りました:
通常、ダイアログを閉じるにはBackキーを押す必要がありますが、Honeycombでは、すべての画面領域のため、ダイアログの外側をタップするだけのオプションがあると便利です。
私のアプリは、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);
}
dialog.setCanceledOnTouchOutside(true)
ウィンドウの境界の外側をタッチしたときにこのダイアログをキャンセルするかどうかを設定します。
ポップアップウィンドウの外側をタッチすると呼び出される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>
_
ダイアログがActivity
の場合、 Activity#setFinishOnTouchOutside も使用できます。それはActivity
sの最短の方法になります;)
(ただし、API 11+です。ただし、API <= 10は通常、通常の画面サイズです。)
使用してもよい
dialog.setCancelable(true\false);
Androidの最新バージョンの場合。
OutSide Touchingイベントを無効にします。
Dialog.setCanceledOnTouchOutside(false);と書くだけです。そしてそれは私のために働いて、窓は外側のタップで消えません。
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);
他のスタイルではなくダイアログのスタイルを使用します。
たとえば、使用
public YourCustomDialog(Context context) {
super(context, Android.R.style.Theme_Holo_dialog_NoActionBar);
}
Theme_Translucent_NoTitleBarなどの他のスタイルを使用する場合、ダイアログは閉じられません。
this.setFinishOnTouchOutside(false);
これを使用できます
古い質問ですが、さらに別の解決策:
前景アクティビティをフルスクリーンにします。ネストされたレイアウト:フルスクリーンレイアウトには透明な背景が必要です(例:_@null
_または_@Android:color/transparent
_)。内部レイアウトには背景が表示されている必要があります。
アクティビティをfinish()
esする非表示の外部レイアウトにOnClickListener
を追加します。
ダイアログ内のすべてのビューは、以下が呼び出されないように、タッチイベントを消費するように設定できます。
onCreate(){
getWindow().getDecorView().getRootView().setOnTouchListener(new OnTouchListener(){
@Override
public boolean onTouch(View v, MotionEvent event) {
dialog.dismiss();
return false;
}
});
LayoutParams lp=dialogp.getWindow().getAttributes();
lp.flags=LayoutParams.FLAG_LAYOUT_NO_LIMITS;
これを追加し、3.0までは問題なく動作しますが、すべてで動作するはずです。