2011-08-27 10 views
37

どういうわけか、ポップアップダイアログ(またはダイアログテーマを持つアクティビティ)の外をタップすることができたら、それを外して閉じることができますか?Androidの外のダイアログをタップして閉じますか?

私はそれを説明するために迅速な絵を作っ:

enter image description here

通常は、ダイアログを閉じ、バックキーを押す必要があるが、ハニカムに、それだけで叩くのオプションを持っているのは素晴らしいことができすべての画面の不動産のため、ダイアログの外にあります。

+1

少なくとも、ダイアログテーマ付きアクティビティの場合、デフォルトの動作であると思います。 –

答えて

47

です。私の場合、他の答えはうまくいかなかった。他のバックグラウンドアプリや起動画面にタッチイベントを受信させるだけでした。

私の場合はdispatchTouchEventを使用していることがわかりました。私はそれももっと簡単な解決策だと思う。ここでダイアログをテーマに活動外のタップを検出するためにそれを使用する方法についていくつかのサンプルコードです:ウィンドウの境界の外に触れたときに、このダイアログがキャンセルされた

@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); 
} 
+12

if条件を 'if(!dialogBounds.contains(int)event.getX()、(int)event.getY())&& event.getAction()== MotionEvent.ACTION_DOWN)に変更すると、そうすれば、ユーザが誤って指を「アクティビティ」の外に動かすと、それは終了しません。 – Glitch

+0

それは素晴らしいです、グリッチ - ありがとう。 –

+1

APIレベル8の使用、テーマ 'android:Theme.Dialog'を使用し、このコードでアクティビティを使用する: 'dialogBounds.top'および' dialogBounds.left'の値は0です。 'dialogBounds.bottom'と' dialogBounds.right'は画面サイズの値を持っており、実際にはdiologウィンドウがフルスクリーンであると考えられます。だから私はこのコードを動作させることはできません。これがなぜ起こっているのか他のアイデアですか? – Jorge

14

ます。たとえば、ポップアップウィンドウ

のうち側に触れたときに

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がポップアップウィンドウ

であり、あなたがのために同じ機能が必要な場合に呼び出されますTouchInterceptor方法がありますアクティビティは以下の手順に従ってください。

1)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で呼び出さsetContentView()メソッドの前にフラグを追加します)完全なコピーがここに

で活動

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

は、これは私のアプリはTheme.Holo.Dialogを持つ単一の活動であるの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> 
+2

これは 'PopupWindow'のためだけです、そうですか?私はHoneycombのTheme.Holo.Dialogテーマで標準アクティビティを使用しています。 –

+0

私は自分の答えを編集しています – Dharmendra

+0

ええ、書いた前に試してみましたが、どちらもうまくいきませんでした:(仕上げのセミコロンがありません)btw :) –

89
dialog.setCanceledOnTouchOutside(true) 

かどうかを設定。

+2

これは最高の解決策です...だから簡単です。なぜこれは答えではないのですか? –

+1

ダイアログテーマのあるアクティビティで作業する必要がありましたが、この場合は機能しませんが、一般的なダイアログのためにアップウィートしました。 –

+3

'this.setFinishOnTouchOutside(false);'ダイアログアクティビティで動作します – Nick

5

ダイアログがActivityの場合は、Activity#setFinishOnTouchOutsideも使用できます。 )

(ただし、API 11+ですが、API < = 10は一般的には画面サイズが標準です。)

+0

を使用するようにDIAを使用し、問題は、アクティビティダイアログなどをテーマに取り組んでいますダイアログではありません。 – JaredBanyard

1

古い質問が、まだ別の解決策:

  1. があなたのフォアグラウンド・アクティビティフルスクリーンにします。慣れ親しんだレイアウト:全画面レイアウトは透明な背景(例えば、@nullまたは@android:color/transparent)を持つ必要があります。内側のレイアウトには背景が表示されている必要があります。

  2. あなたのアクティビティがfinish()である目に見えない外枠にOnClickListenerを追加します。

0

ダイアログ内の任意のビューは、タッチイベントを消費するように設定されているため、以下は呼び出されません。

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

私はこれを追加し、それが3.0までに完璧に動作しますが、すべてで動作するはずです。

1

他のスタイルではなくダイアログのスタイルを使用します。あなたはTheme_Translucent_NoTitleBarのような他のスタイルを使用する場合たとえば

は、

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

を使用して、ダイアログが却下されることはありません。

5

あなたは、Androidの最新のvesrionsについて

dialog.setCancelable(true\false); 

を使用することができます。

outSideTouchingイベントを無効にします。あなたがコードやない....

dialog.setCanceledOnTouchOutside(true); 
+0

どのバージョンですか? – AbleArcher

+0

KITKATを除くすべてのバージョンでテスト済みです:) – Amt87

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

。それは私のために働く、窓は外のタップで却下しません。

4

のこのラインを持っている場合は、チェックは単に私がdialog.setCanceledOnTouchOutside(false)を書く

1

this.setFinishOnTouchOutside(false);

あなたはこれを使うことができます

関連する問題