Androidアクティビティダイアログが外部のタッチで閉じないようにする


229

Theme.Dialogスタイルを使用しているアクティビティがあるため、別のアクティビティの上にフローティングウィンドウが表示されます。しかし、ダイアログウィンドウの外側(バックグラウンドアクティビティ上)をクリックすると、ダイアログが閉じます。この動作を停止するにはどうすればよいですか?


1
なぜあなたはそれをしますか?必要な動作がダイアログの場合は、ダイアログを使用してみませんか?あなたの質問に来て、私にはそれに対する解決策はないと思います。
Kumar Bibek 2012

@KumarBibekダイアログは、レイアウトのカスタマイズに関しては制限されています...それがアクティビティです。開発者のドキュメントでさえ、柔軟なカスタマイズのためにこのアプローチを推奨しています
Leo

1
OPが望むのは、モーダルダイアログ、つまりユーザーに[OK]や[はい/いいえ]などの応答を強制するダイアログです。ユーザーはクリックするだけではいけません。
Scott Biggs

回答:


34

これはあなたを助けるでしょう。これは、タッチ外部イベントを処理する方法です。

ウィンドウの外でタッチしたときに、アクティビティをテーマにしたダイアログをキャンセルするにはどうすればよいですか?

イベントをキャッチして何もしないことで、クローズを防ぐことができると思います。ただし、奇妙なのは、アクティビティダイアログのデフォルトの動作では、外に触れたときにそれ自体が閉じないようにすることです。

(PS:コードはWindowManager.LayoutParamsを使用します)


1
オブジェクトはダイアログではありませんが、ダイアログスタイルを使用するアクティビティです。アクティビティにはこのメソッドがなく、Dialogにキャストできません。
Fergusmac 2012

あなたの投稿は、尋ねられたものの正反対です。彼はそれを引き起こす方法ではなく、どのように閉じるのを防ぐかを尋ねました。
ChuckKelly 2013

4
それは彼が「イベントをキャッチして何もしないことで、クローズを防ぐことができる」と説明したものです。
メッター2013年

4
なんらかの理由で、FLAG_NOT_MODAL、WATCH_OUTSIDE_TOUCH全体を実行した後、外側のタッチは実際にはアクティビティを閉じませんが、アクティビティの背後にあるボタンがクリックされます。そのためのアイデア?
njzk2 2013年

ダイアログには影があることに注意してください(少なくとも現在(8.0)まで)。影をクリックすると、Androidはダイアログ内と同じようにそのクリックを解釈します。これを世界と共有したかっただけで、取得するのに10分かかりました。
ロレンツォフォンマッターホルン

458

戻るキーが押されたときにダイアログボックスが閉じないようにするには、これを使用します

dialog.setCancelable(false);

そして、ダイアログボックスが外部のタッチで閉じられるのを防ぐために、これを使用してください

 dialog.setCanceledOnTouchOutside(false);

4
この回答は役に立ちますが、この質問はTheme.Dialog属性を使用したアクティビティに関するものです。
Paresh Mayani 2014

15
それが多くの人々を助けるのでそれを削除しなかったのでそれが遅すぎることに気付いたとき私は知っています。
Singhak 2014

12
これが問題に実際には関係していなかったことは知っていますが、これは私を助けました。ありがとう!
dennisdrew 2014年

5
これが最良の答えです。私は、この質問を見つけたほとんどの人々が、標準AlertDialogが外で閉ざされないようにする方法を探しているのではないかと思います。それが、この回答が提供するものです。
2016

20
AlertDialogの新しいバージョンでは、使用する必要があるだけですsetCancelable(false)
Kobi Tate

120

実際に持っているのは(ダイアログのように見えても)アクティビティなのでsetFinishOnTouchOutside(false)、バックグラウンドアクティビティがクリックされたときに開いたままにしたい場合は、アクティビティから呼び出す必要があります。

編集:これはAndroid APIレベル11以上でのみ機能します


4
これは、アクティビティの「戻る」ボタンを押すことを妨げるものではありません。したがってonBackPressed()、本文で何もしないこともオーバーライドする必要があります。
Alex Bonel

onBackPressed()なしのダイアログアクティビティの「戻る」ボタンを妨げていません。this.setFinishOnTouchOutside(false)で完璧に動作します。
Kunalxigxag 2014年

68

私にとってうまくDialogFragmentいったのは、キャンセルできないようにセットを作成することでした:

dialog.setCancelable(false);

1
役に立たなかった。この質問は、ダイアログではなく、アクティビティについてです。
Scott Biggs

20

ダイアログをonCreateのアクティビティとして使用する場合、これを追加します

setFinishOnTouchOutside(false);

17

高いAPI 10の場合、ダイアログは外側をタッチすると消えますが、API 11より低い場合、ダイアログは消えません。これを防ぐには、次のことを行う必要があります。

styles.xml<item name="android:windowCloseOnTouchOutside">false</item>

または

ではonCreate()方法、使用します。this.setFinishOnTouchOutside(false);

注:API 10以下の場合、このメソッドは効果がなく、必要ありません。


14

キャンセル可能なダイアログをfalseに設定するだけで十分です。アラートダイアログの外側をタッチするか、戻るボタンをクリックすると、アラートダイアログが非表示になります。だからこれを使う:

setCancelable(false)

そして、他の機能はもう必要ありません: dialog.setCanceledOnTouchOutside(false);

一時的なダイアログを作成していて、このコード行を配置しようと思っている場合は、次の例をご覧ください。

new AlertDialog.Builder(this)
                        .setTitle("Trial Version")
                        .setCancelable(false)
                        .setMessage("You are using trial version!")
                        .setIcon(R.drawable.time_left)
                        .setPositiveButton(android.R.string.yes, null).show();

12

それが私のために働いているこのコードを使用してください

 AlertDialog.Builder alertDialog = new AlertDialog.Builder(this);
 alertDialog.setCancelable(false);


もし彼が正しい質問をすることができれば、これは正しい答えであるべきです!
alijunior 2016

2
OPがダイアログについて質問した場合、これは正しい答えです。しかし、問題はアクティビティについてです。まったく別のケースです。
Scott Biggs

11
Dialog dialog = new Dialog(context)
dialog.setCanceledOnTouchOutside(true); 
//use this to dismiss the dialog on outside click of dialog

dialog.setCanceledOnTouchOutside(false);
//use this for not to dismiss the dialog on outside click of dialog.

ダイアログの詳細については、このリンクをご覧ください

dialog.setCancelable(false);
//used to prevent the dismiss of dialog on backpress of that activity

dialog.setCancelable(true);
//used to dismiss the dialog on onbackpressed of that activity

質問は、ダイアログクラスではなく、ダイアログとして使用されるアクティビティに関係することに注意してください。
Scott Biggs

8

単に、

alertDialog.setCancelable(false);

ユーザーがダイアログボックスの外側をクリックできないようにします。


7

Alert Dialogは非推奨であるため、Dialog dialog = new Dialog(this);を使用してください。

外のタッチでの接近を防ぐため

dialog.setCanceledOnTouchOutside(false);

5

setFinishOnTouchOutside(false)API> 11に使用します。アクティビティをテーマにしたダイアログがAPI <11の外部タッチで終了しないというAndroidのデフォルトの動作なので心配する必要はありません。


5

私はこれをonCreate()で使用しています。Androidのどのバージョンでも機能するようです。5.0および4.4.xでテストされていますが、Gingerbreadではテストできません。Samsungデバイス(GBを実行している注1)では、デフォルトで次のようになっています。

    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB)
    {
        setFinishOnTouchOutside(false);
    }
    else
    {
        getWindow().clearFlags(LayoutParams.FLAG_WATCH_OUTSIDE_TOUCH);
    }

    super.onCreate(savedInstanceState);

4
        alert.setCancelable(false);
        alert.setCanceledOnTouchOutside(false);

これはあなたに役立つと思います。


1
なぜこれが機能するのか説明してみてください...コードダンプだけでは良い答えではありません。
Codebender 2015

3

これが私の解決策です:

AlertDialog.Builder builder = new AlertDialog.Builder(this);
builder.setTitle("Select The Difficulty Level");
builder.setCancelable(false);

2

onCancelListenerを実装するさまざまなアクションを割り当てることもできます。

alertDialog.setOnCancelListener(new DialogInterface.OnCancelListener(){                   
    @Override
    public void onCancel(DialogInterface dialogInterface) {
        //Your custom logic
    } 
});

警告ダイアログの外側をタップしたためにキャンセルが呼び出されたかどうかを確認するにはどうすればよいですか?
cegprakash

警告ダイアログの外側をタップするカスタムアクションを作成するのに非常に役立ちます。
Adam S.

1

私も同じ問題に直面していました。それを処理するOntouchListenerには、ダイアログにaを設定し、内部では何もしません。ただし、画面を回転させるとダイアログが閉じます。それを修正するために、ダイアログが正常に終了したかどうかを通知する変数を設定しました。次にOnDismissListener、ダイアログにaを設定し、内部で変数をチェックします。ダイアログが正常に解除された場合、私は何もしません、またはダイアログを再度実行します(そして、私のケースでは、ダイアログを閉じるときの状態を設定します)。


1

builder.setCancelable(false);


public void Mensaje(View v){

    AlertDialog.Builder builder = new AlertDialog.Builder(this);
    builder.setTitle("¿Quieres ir a el Menú principal?");
    builder.setMessage("Al presionar SI iras a el menú y saldras de la materia.");
    builder.setPositiveButton("SI", null);
    builder.setNegativeButton("NO", null);
    builder.setCancelable(false);
    builder.show();
}

1
やあアレックス。StackOverflowへようこそ。ご回答いただきありがとうございます。答えを編集して、コードが何をするか、これがOPの問題をどのように解決するかを説明していただけませんか?コードのみの回答は、その理由を教えたり説明したりしないため、推奨されません。ありがとうございました!
Tim Malone

-1

これは、すべての質問に対する完全な回答です。Androidでコーディングを楽しんでください。

new AlertDialog.Builder(this)
            .setTitle("Akshat Rastogi Is Great")
            .setCancelable(false)
            .setMessage("I am the best Android Programmer")
            .setPositiveButton("I agree", new DialogInterface.OnClickListener() {
                @Override
                public void onClick(DialogInterface dialog, int which) {
                    dialog.dismiss();

                }
            })
            .create().show();

このコードスニペットをありがとうございます。このコードスニペットは、制限された即時のヘルプを提供する可能性があります。適切な説明は、なぜこれが問題の優れた解決策であるかを示すことにより、長期的な価値を大幅に改善し、他の同様の質問を持つ将来の読者にとってより有用になるでしょう。回答を編集して、仮定を含めて説明を追加してください。
Maximilian Peters
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.