防止Android活动对话框因外部触摸而关闭


228

我有一个使用Theme.Dialog样式的活动,因此它是另一个活动上方的浮动窗口。但是,当我在对话框窗口外部(在后台活动上)单击时,对话框关闭。如何停止这种行为?


1
你为什么要那样做。如果您想要的行为是对话框,为什么不使用对话框?谈到您的问题,我认为没有解决方案。
库玛·比贝克

@KumarBibek对话框在布局自定义方面受到限制...这就是活动的原因。甚至开发人员文档也推荐这种方法进行灵活的自定义
Leo

1
OP想要的是模式对话框,即强制用户响应的对话框,例如“确定”或“是/否”。用户应该不能仅单击即可。
Scott Biggs

Answers:


33

这可以帮助您。这是处理外部触摸事件的一种方式:

在窗口外触摸时如何取消以活动为主题的对话框?

我认为通过抓住事件而不采取任何措施,您可以防止比赛结束。但是,奇怪的是,活动对话框的默认行为是当您触摸外部时关闭自身。

(PS:代码使用WindowManager.LayoutParams)


1
该对象不是对话框,而是使用对话框样式的Activity。活动没有此方法,因此无法强制转换为Dialog。
Fergusmac

您的职位与要求完全相反。他问如何防止关闭而不是造成关闭。
ChuckKelly 2013年

4
这就是他用“通过抓住事件而不采取任何措施,我认为您可以防止结束”的解释。
2013年

4
由于某种原因,在完成整个FLAG_NOT_MODAL,WATCH_OUTSIDE_TOUCH之后,外部触摸实际上并没有关闭活动,而是单击了活动后面的按钮。有什么想法吗?
njzk2

请注意,对话框有一个阴影(至少到目前为止(8.0)):如果单击阴影,Android会像单击对话框内部一样解释该单击。只是想与全世​​界分享,我花了10分钟才得到它。
罗伦佐·冯·马特洪峰'18

458

为了防止对话框在按下返回键时被关闭,请使用此

dialog.setCancelable(false);

并且为了防止对话框因外界触摸而被解散,请使用此

 dialog.setCanceledOnTouchOutside(false);

4
这个答案很有帮助,但是这个问题是关于使用Theme.Dialog属性的活动。
Paresh Mayani 2014年

15
我知道我意识到这为时已晚,因为它帮助了很多人,所以没有删除它。
Singhak

12
我知道这与问题无关,但这对我有所帮助。谢谢!
dennisdrew 2014年

5
这是最好的答案。我怀疑大多数发现此问题的人都在寻找一种方法,以防止标准AlertDialog在接触外部时关闭,而这正是该答案所提供的。
aroth '16

20
在较新版本的AlertDialog上,您只需使用setCancelable(false)
Kobi Tate

120

您实际拥有的是一个活动(即使它看起来像一个对话框),因此,setFinishOnTouchOutside(false)如果要在单击后台活动时使其保持打开状态,则应从活动中调用。

编辑:这仅适用于android API级别11或更高


4
这不会阻止您在活动中按下“返回”按钮。因此,您还需要超越onBackPressed()对身体不执行任何操作的
权限

没有onBackPressed()的对话框活动中不会阻止“后退”按钮。与this.setFinishOnTouchOutside(false)完美搭配。
Kunalxigxag 2014年

68

对我有用的是创建DialogFragment一个不可取消的集合:

dialog.setCancelable(false);

1
没有帮助。这个问题是关于活动,而不是对话框。
斯科特·比格斯


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

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

请注意,该问题与用作对话框的活动有关,而不是与Dialog类有关。
Scott Biggs

8

只是,

alertDialog.setCancelable(false);

防止用户在对话框外部单击。


6

不建议使用“警告对话框”,因此请使用“对话框对话框” =“新对话框”(this);

为了防止外部接触

dialog.setCanceledOnTouchOutside(false);

5

使用setFinishOnTouchOutside(false)的API> 11,不要担心,因为它的Android的默认行为活动的主题对话将不会对外界触摸完成了API <11 :)!Cheerss!


5

我在onCreate()中使用了它,似乎可以在任何版本的Android上使用;在5.0和4.4.x上进行了测试,无法在Gingerbread上进行测试,默认情况下,三星设备(运行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


2

也可以分配不同的操作来实现onCancelListener:

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

如何确定是否由于在警报对话框外点击而取消调用?
cegprakash

在警报对话框外部点击时创建自定义操作非常有帮助!
亚当S.19年

1

我面临着同样的问题。为了处理它,我OntouchListener在对话框中设置了a ,而在对话框中什么也不做。但是对话框在旋转屏幕时也关闭。为了解决这个问题,我设置了一个变量来告诉我该对话框是否正常关闭。然后OnDismissListener,在对话框中设置a 并在其中检查变量。如果对话框通常已关闭,那么我什么也不做,否则我将再次运行该对话框(并将其状态设置为在我的情况下关闭时)。


1

builder.setCancelable(false);


公共无效的Mensaje(查看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的问题?不鼓励仅使用代码的答案,因为它们不会教授或解释原因。谢谢!
蒂姆·马隆

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

感谢您提供此代码段,它可能会提供一些有限的即时帮助。通过说明为什么这是一个很好的解决方案,正确的解释将大大提高其长期价值,对于其他存在类似问题的读者来说,这样做将更为有用。请编辑您的答案以添加一些解释,包括您所做的假设。
马克西米利安·彼得斯
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.