如何防止单击按钮时关闭对话框
我有一个带有 EditText
的对话框用于输入。当我单击对话框上的“是”按钮时,它将验证输入,然后关闭对话框。但是,如果输入错误,我想保留在同一个对话框中。每次无论输入什么,当我单击“否”按钮时,对话框都应该自动关闭。我怎样才能禁用这个功能?顺便说一句,我使用 PositiveButton 和 NegativeButton 作为对话框上的按钮。
I have a dialog with EditText
for input. When I click the "yes" button on dialog, it will validate the input and then close the dialog. However, if the input is wrong, I want to remain in the same dialog. Every time no matter what the input is, the dialog should be automatically closed when I click on the "no" button. How can I disable this? By the way, I have used PositiveButton and NegativeButton for the button on dialog.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(21)
编辑:正如一些评论所述,这只适用于 API 8+。
这是一个迟到的答案,但您可以将 onShowListener 添加到 AlertDialog,然后您可以在其中覆盖按钮的 onClickListener。
EDIT: This only works on API 8+ as noted by some of the comments.
This is a late answer, but you can add an onShowListener to the AlertDialog where you can then override the onClickListener of the button.
以下是适用于所有类型对话框的一些解决方案,包括适用于所有 API 级别的 AlertDialog.Builder 解决方案(适用于 API 8 以下,而此处的其他答案则不然)。有使用 AlertDialog.Builder、DialogFragment 和 DialogPreference 的 AlertDialog 解决方案。
下面的代码示例显示了如何覆盖默认的通用按钮处理程序并防止这些不同形式的对话框关闭。所有示例都展示了如何防止肯定按钮关闭对话框。
注意:对于那些想要了解更多详细信息的人,在示例后面将描述对话框关闭如何在 Android 基类的底层工作以及为什么选择以下方法
AlertDialog.Builder - 在 show() 之后立即更改默认按钮处理程序
DialogFragment - 覆盖 onResume()
DialogPreference - 覆盖 showDialog()
方法说明:
Here are some solutions for all types of dialogs including a solution for AlertDialog.Builder that will work on all API levels (works below API 8, which the other answer here does not). There are solutions for AlertDialogs using AlertDialog.Builder, DialogFragment, and DialogPreference.
Below are the code examples showing how to override the default common button handler and prevent the dialog from closing for these different forms of dialogs. All the examples show how to prevent the positive button from closing the dialog.
Note: A description of how the dialog closing works under the hood for the base android classes and why the following approaches are chosen follows after the examples, for those who want more details
AlertDialog.Builder - Change default button handler immediately after show()
DialogFragment - override onResume()
DialogPreference - override showDialog()
Explanation of approaches:
替代解决方案
我想从用户体验的角度提出替代答案。
为什么要阻止单击按钮时关闭对话框?大概是因为您有一个自定义对话框,其中用户尚未做出选择或尚未完全填写所有内容。如果他们还没有完成,那么你根本不应该允许他们点击肯定按钮。只需禁用它,直到一切准备就绪。
这里的其他答案提供了很多覆盖肯定按钮点击的技巧。如果这件事很重要,Android 是否会提供一种方便的方法来做到这一点?他们没有。
相反,对话框设计指南显示了此类情况的示例。在用户做出选择之前,“确定”按钮将被禁用。根本不需要压倒性的技巧。对于用户来说,显然在继续之前还需要做一些事情。
如何禁用肯定按钮
请参阅 Android 文档用于创建自定义对话框布局。它建议您将
AlertDialog
放置在DialogFragment
中。然后,您需要做的就是在布局元素上设置侦听器,以了解何时启用或禁用肯定按钮。EditText
,请使用 TextWatcher< /a>.可以像这样禁用肯定按钮:
这是一个完整的工作
DialogFragment
,其中包含禁用的肯定按钮,如上图中可能使用的那样。自定义对话框可以从这样的活动中运行:
注释
该按钮在
onCreateDialog
中仍然为null
,因此我在onResume
中禁用了它。如果用户切换到另一个应用程序然后返回而不关闭该对话框,则会产生再次禁用它的不良效果。也可以通过取消选择任何用户选项或从onCreateDialog
调用Runnable
来禁用下一个运行循环上的按钮来解决此问题。相关
An alternate solution
I would like to present an alternate answer from a UX perspective.
Why would you want to prevent a dialog from closing when a button is clicked? Presumably it is because you have a custom dialog in which the user hasn't made a choice or hasn't completely filled everything out yet. And if they are not finished, then you shouldn't allow them to click the positive button at all. Just disable it until everything is ready.
The other answers here give lots of tricks for overriding the positive button click. If that were important to do, wouldn't Android have made a convenient method to do it? They didn't.
Instead, the Dialogs design guide shows an example of such a situation. The OK button is disabled until the user makes a choice. No overriding tricks are necessary at all. It is obvious to the user that something still needs to be done before going on.
How to disable the positive button
See the Android documentation for creating a custom dialog layout. It recommends that you place your
AlertDialog
inside aDialogFragment
. Then all you need to do is set listeners on the layout elements to know when to enable or disable the positive button.EditText
, then use TextWatcher.The positive button can be disabled like this:
Here is an entire working
DialogFragment
with a disabled positive button such as might be used in the image above.The custom dialog can be run from an activity like this:
Notes
The button is still
null
inonCreateDialog
so I disabled it inonResume
. This has the undesireable effect of disabling the it again if the user switches to another app and then comes back without dismissing the dialog. This could be solved by also unselecting any user choices or by calling aRunnable
fromonCreateDialog
to disable the button on the next run loop.Related
我编写了一个简单的类(AlertDialogBuilder),您可以使用它在按下对话框按钮时禁用自动关闭功能。
它也与 Android 1.6 兼容,因此它不使用 OnShowListener(仅 API >= 8 可用)。
因此,您可以使用此 CustomAlertDialogBuilder,而不是使用 AlertDialog.Builder。
最重要的部分是您不应该调用 create(),而只能调用 show() 方法。我添加了 setCanceledOnTouchOutside() 和 setOnDismissListener 等方法,以便您仍然可以直接在构建器上设置它们。
我在 Android 1.6、2.x、3.x 和 4.x 上测试了它,所以它应该运行得很好。
如果您发现一些问题,请在这里评论。
编辑这是一个有关如何使用 CustomAlertDialogBuilder 的小示例:
干杯,
Yuvi
I've written a simple class (an AlertDialogBuilder) that you can use to disable the auto-dismiss feature when pressing the dialog's buttons.
It is compatible also with Android 1.6, so it doesn't make use of the OnShowListener (which is available only API >= 8).
So, instead of using AlertDialog.Builder you can use this CustomAlertDialogBuilder.
The most important part is that you should not call create(), but only the show() method. I've added methods like setCanceledOnTouchOutside() and setOnDismissListener so that you can still set them directly on the builder.
I tested it on Android 1.6, 2.x, 3.x and 4.x so it should work pretty well.
If you find some problems please comment here.
EDIT Here is a small example on how to use the CustomAlertDialogBuilder:
Cheers,
Yuvi
如果您使用
DialogFragment
,这里有一些东西 - 无论如何,这是处理对话框的推荐方法。AlertDialog 的
setButton()
方法会发生什么(我想与AlertDialogBuilder
的setPositiveButton()
和setNegativeButton()< /code>)是,您设置的按钮(例如
AlertDialog.BUTTON_POSITIVE
)在按下时实际上会触发两个不同的OnClickListener
对象。第一个是 DialogInterface.OnClickListener,它是 <代码>setButton()、
setPositiveButton()
和setNegativeButton()
。另一个是 View.OnClickListener,它将自动设置为当按下任何按钮时关闭您的
AlertDialog
- 并且由AlertDialog
本身设置。您可以做的是使用
setButton()
和null
作为DialogInterface.OnClickListener
,创建按钮,然后调用您的自定义操作View.OnClickListener
中的方法。例如,然后,您可以在
DialogFragment
中覆盖默认的AlertDialog
按钮的View.OnClickListener
(否则会关闭对话框)的onResume()
方法:您需要在
onResume()
方法中设置此项,因为getButton()
将返回null
直到对话框显示之后!这应该会导致您的自定义操作方法仅被调用一次,并且默认情况下不会关闭对话框。
Here's something if you are using
DialogFragment
- which is the recommended way to handle Dialogs anyway.What happens with AlertDialog's
setButton()
method (and I imagine the same withAlertDialogBuilder
'ssetPositiveButton()
andsetNegativeButton()
) is that the button you set (e.g.AlertDialog.BUTTON_POSITIVE
) with it will actually trigger TWO differentOnClickListener
objects when pressed.The first being DialogInterface.OnClickListener, which is a parameter to
setButton()
,setPositiveButton()
, andsetNegativeButton()
.The other is View.OnClickListener, which will be set to automatically dismiss your
AlertDialog
when any of its button is pressed - and is set byAlertDialog
itself.What you can do is to use
setButton()
withnull
as theDialogInterface.OnClickListener
, to create the button, and then call your custom action method insideView.OnClickListener
. For example,Then, you may override the default
AlertDialog
's buttons'View.OnClickListener
(which would otherwise dismiss the dialog) in theDialogFragment
'sonResume()
method:You will need to set this in the
onResume()
method becausegetButton()
will returnnull
until after the dialog has been shown!This should cause your custom action method to only be called once, and the dialog won't be dismissed by default.
受汤姆回答的启发,我相信这里的想法是:
onClickListener
设置为null
您可以像 Tom 一样重写
onShowListener
。或者,您可以show()
后获取按钮,onClickListener
如下(我认为可读性更好一些)。代码:
Inspired by Tom's answer, I believe the idea here is:
onClickListener
during the creation of the dialog tonull
onClickListener
after the dialog is shown.You can override the
onShowListener
like Tom. Alternatively, you canshow()
onClickListener
as follows (slightly more readable I think).Code:
超级简单的 Kotlin 方法
Super simple Kotlin approach
对于 API 8 之前的版本,我使用布尔标志、关闭侦听器解决了问题,并在 editText 的内容不正确时再次调用dialog.show。像这样:
For pre API 8 i solved the problem using a boolean flag, a dismiss listener and calling dialog.show again if in case the content of the editText wasn´t correct. Like this:
此链接的答案是一个简单的解决方案,并且与 API 3 兼容。它与 Tom 非常相似Bollwitt 的解决方案,但没有使用兼容性较差的 OnShowListener。
自从扩展 EditTextPreference 以来,我对 Kamen 的代码做了一些小的调整。
真有趣!
The answer at this link is a simple solution, and which is compatible right back to API 3. It is very similiar to Tom Bollwitt's solution, but without using the less compatible OnShowListener.
I made minor adaptions to Kamen's code since I was extending an EditTextPreference.
Such fun!
这段代码对你有用,因为我有一个类似的问题,这对我有用。 :)
1- 重写片段对话框类中的 Onstart() 方法。
This code will work for you, because i had a simmilar problem and this worked for me. :)
1- Override Onstart() method in your fragment-dialog class.
为了防止对话框在单击时关闭,并且仅在互联网可用时关闭,
我正在尝试做同样的事情,因为我不希望对话框关闭,直到并且除非互联网已连接。
这是我的代码:
这是我的连接管理器代码:
To prevent Dialog box from closing when clicked and it should only close when the internet is available
I am trying to do the same thing, as I don't want the dialog box to be closed until and unless the internet is connected.
Here is my code:
And here is my Connectivity manager code:
使用此代码,您可以防止单击肯定按钮时关闭对话框。您也可以使用否定按钮实现相同的效果。
With this code you can prevent dialog from closing when positive button clicked. Also you can implement the same with the negative button.
对于 ProgressDialogs
要防止对话框自动关闭,您必须在显示
ProgressDialog
之后设置OnClickListener
,如下所示:For ProgressDialogs
To prevent the dialog from being dismissed automatically you have to set the
OnClickListener
after theProgressDialog
is shown, like so:你可以添加 builder.show();返回之前验证消息之后;
像这样
you can add builder.show(); after validation message before return;
like this
如果您使用
材料设计
,我建议您查看material-dialogs 。它为我解决了与当前未解决的 Android 错误相关的几个问题(请参阅 78088),但对于这张票最重要的是,它有一个autoDismiss
标志,可以在使用Builder
时设置。If you are using
material design
I would suggest checking out material-dialogs. It fixed several issues for me related to currently open Android bugs (see 78088), but most importantly for this ticket it has anautoDismiss
flag that can be set when using theBuilder
.为您的
DialogFragment
使用自定义布局,并在您的内容下添加一个LinearLayout
,其样式可以设置为无边框,以匹配 Google Material Design。然后找到新创建的按钮并覆盖它们的OnClickListener
。示例:
dialog_add_topic.xml:
这是最终结果。
Use a custom layout for your
DialogFragment
and add aLinearLayout
under your content which can be styled as borderless to match Google Material Design. Then find the newly created buttons and override theirOnClickListener
.Example:
dialog_add_topic.xml:
This is the final result.
Kotlin
我们只需使用
dialogBuilder
创建一个AlertDialog
,然后根据需要设置肯定按钮Kotlin
We just create an
AlertDialog
with thedialogBuilder
and then just set the positive button as we want它可以用最简单的方法构建:
带有自定义视图和两个按钮(正面和负面)的警报对话框。
警报对话的积极按钮的CustomClickLister:
完成
It could be built with easiest way:
Alert Dialog with Custom View and with two Buttons (Positive & Negative).
CustomClickLister of Positive Button of Alert Dailog:
Done
我找到了另一种方法来实现此目的...
第 1 步:将对话框打开代码放入方法(或 C 中的函数)。
步骤 2:在
yes
(Your PositiveButton) 的 onClick 中,调用此对话框打开如果不满足条件,则递归调用方法(通过使用 if...else...)。如下所示:
但这会使对话框消失一会儿,然后立即再次出现。 :)
I found an other way to achieve this...
Step 1: Put the dialog opening code in a method (Or Function in C).
Step 2: Inside the onClick of
yes
(Your positiveButton), call this dialog openingmethod recursively if your condition is not satisfied (By using if...else...). Like below :
But this will make the dialog disappear just for a moment and it will appear again instantly. :)
这可能是很晚的回复,但使用 setCancelable 可以解决问题。
This is probably very late reply, but using setCancelable will do the trick.