在对话框外发生单击时如何触发事件
Posted
技术标签:
【中文标题】在对话框外发生单击时如何触发事件【英文标题】:How do I fire an event when click occurs outside a dialog 【发布时间】:2012-03-19 22:51:12 【问题描述】:我想知道如何解决我遇到的问题。
我有一个在活动中弹出的对话框。对话框没有覆盖整个屏幕,因此活动中的按钮仍然显示。当在对话框边界之外触摸dialog.setCanceledOnTouchOutside(true);
时,我可以轻松关闭对话框
但是,如果单击超出 Dialog 的范围,我想做的是触发事件(例如,如果有人触摸主 Activity 上的按钮,它应该关闭 Dialog 并同时触发该事件)。
【问题讨论】:
正常的解决方案是使对话框模式化。你为什么不想这样做? 谢谢。我试图在我的主要活动中显示一个 webview(在对话框中),以便它保持应用程序的外观。 【参考方案1】:当dialog.setCanceledOnTouchOutside(true);
时,您只需像这样覆盖onCancel()
:
dialog.setOnCancelListener(
new DialogInterface.OnCancelListener()
@Override
public void onCancel(DialogInterface dialog)
//When you touch outside of dialog bounds,
//the dialog gets canceled and this method executes.
);
在onCancel()
方法中输入您的代码,以便在对话框取消时运行。
【讨论】:
最佳答案.. 2 年后也参考相同的答案...无法再次投票:) OVERRIDING Dialog.onCancel(...) 有效,但 dialog.setOnCancelListener(...) 对我不起作用。 什么时候? -When dialog.setCanceledOnTouchOutside(true);
这是默认行为...
这应该是公认的答案!!多么棒的答案。【参考方案2】:
它对我有用,
Window window = dialog.getWindow();
window.setFlags(WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL,
WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL);
window.clearFlags(WindowManager.LayoutParams.FLAG_DIM_BEHIND);
dialog.show();
看到这个http://developer.android.com/reference/android/view/WindowManager.LayoutParams.html#FLAG_NOT_TOUCH_MODAL
【讨论】:
这有点用。只有我可以滚动列表视图但不能单击它。【参考方案3】:在DialogFragment
中你可以使用AlertDialog
和@silverTech 的答案:
override fun onDismiss(dialog: DialogInterface)
yourMethod()
super.onDismiss(dialog)
或
override fun onCancel(dialog: DialogInterface)
yourMethod()
super.onCancel(dialog)
【讨论】:
为什么建议在 super.onDismiss() 之前插入逻辑?那为什么super.onCancel()后面是逻辑呢? @AJW,我打开了DialogFragment
。 onCancel
是空的,而 onDismiss
包含一些关于关闭(关闭)对话框的逻辑。我建议先编写您的逻辑,然后再销毁方法(super.onPause()
、onDestroy
、onSaveInstanceState
等)。最好在系统销毁对象之前完成变量。所以,也许最好删除super.onCancel(dialog)
。在您发表评论后,我重写了onCancel
,谢谢。【参考方案4】:
您可以使用OnCancelListener 在对话框外发生点击时触发事件:
dialog.setOnCancelListener(new DialogInterface.OnCancelListener()
@Override
public void onCancel(DialogInterface dialog)
yourFunction();
);
【讨论】:
它与@WillNeithan 回答 (***.com/a/28709752/2914140) 有何不同?【参考方案5】:如果您在自定义对话框类中,并且希望捕捉“点击外部”事件 - 覆盖取消()。如果你想捕捉“对话框关闭”事件 - 覆盖dismiss()。 我建议在 super.dismiss() 之前插入逻辑。 Kotlin 示例:
override fun dismiss()
Utils.hideKeyboard(mContext, window)
super.dismiss()
【讨论】:
不是一个很好的答案。意思是,它不是通用的。我必须写新的行为,而不是注意到旧的行为。在我制作通用对话框实用程序的情况下,我无法知道对话框背后的内容。 @JaveneCPPMcGowan 您可以使用自定义对话框中的回调到视图。 正如我所说,这是新的行为。 @SilverTech 为什么建议在 super.dismiss() 之前插入逻辑? 反之则造成了只有有时 hideKeyboard 函数才能按预期工作的情况。【参考方案6】:它可以在com.google.android.material.bottomsheet.BottomSheetDialog
获得
> // We treat the CoordinatorLayout as outside the dialog though it is technically inside
> coordinator
> .findViewById(R.id.touch_outside)
> .setOnClickListener(
> new View.OnClickListener()
> @Override
> public void onClick(View view)
> if (cancelable && isShowing() && shouldWindowCloseOnTouchOutside())
> cancel();
>
>
> );
这样您就可以在 BottomSheetDialog 覆盖 ClickListener
class MyBottomDialogFragment : BottomSheetDialogFragment()
override fun onCreateDialog(savedInstanceState: Bundle?): Dialog
val dialog = object : BottomSheetDialog(activity as Context, theme)
private var isDialogCancelable: Boolean = false
private var isDialogCancelableOnTouchOutside: Boolean = false
override fun onBackPressed()
handleBackPressed(this)
override fun setContentView(layoutResId: Int)
super.setContentView(layoutResId)
setupTouchOutside()
override fun setContentView(view: View?)
super.setContentView(view)
setupTouchOutside()
override fun setContentView(view: View?, params: ViewGroup.LayoutParams?)
super.setContentView(view, params)
setupTouchOutside()
private fun setupTouchOutside()
val coordinator = findViewById<View>(com.google.android.material.R.id.coordinator) as CoordinatorLayout
// We treat the CoordinatorLayout as outside the dialog though it is technically inside
coordinator
.findViewById<View>(com.google.android.material.R.id.touch_outside)
.setOnClickListener
if (isDialogCancelable && isShowing && isDialogCancelableOnTouchOutside)
handleTouchOutside(this)
override fun setCancelable(cancelable: Boolean)
super.setCancelable(cancelable)
isDialogCancelable = cancelable
override fun setCanceledOnTouchOutside(cancel: Boolean)
super.setCanceledOnTouchOutside(cancel)
isDialogCancelableOnTouchOutside = cancel
dialog.window?.setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_ADJUST_RESIZE)
dialog.setCanceledOnTouchOutside(true)
return dialog
protected open fun handleBackPressed(dialog: BottomSheetDialog)
/* do what you want but after that call dialog.cancel() or dialog.dismiss() */
protected open fun handleTouchOutside(dialog: BottomSheetDialog)
/* do what you want but after that call dialog.cancel() or dialog.dismiss() */
【讨论】:
【参考方案7】:使用返回按钮命令返回上一屏幕。
在扩展 DialogFragment 的类中使用覆盖方法 onCancel。 . .
@Override
public void onCancel(@NonNull DialogInterface dialog)
super.onCancel(dialog);
getParentFragment().getActivity().onBackPressed();
【讨论】:
【参考方案8】:我发现所有其他答案都非常冗长和复杂,所以我使用了这种方法:
第 1 步: 为要为其生成点击外部事件的元素的外部容器创建一个 ID。
在我的例子中,它是一个线性布局,我将其 id 指定为“outsideContainer”
第 2 步: 为该外部容器设置一个 onTouchListener,它只会充当您内部元素的外部点击事件!
outsideContainer.setOnTouchListener(new View.OnTouchListener()
@Override
public boolean onTouch(View v, MotionEvent event)
// perform your intended action for click outside here
Toast.makeText(YourActivity.this, "Clicked outside!", Toast.LENGTH_SHORT).show();
return false;
);
【讨论】:
以上是关于在对话框外发生单击时如何触发事件的主要内容,如果未能解决你的问题,请参考以下文章
c#双击 dataGridView 会触发CellContentClick 怎么点击dataGridView会触发CellClick事件