我想知道如何解决我遇到的问题。
我有一个在活动中弹出的对话框。对话框没有覆盖整个屏幕,因此活动中的按钮仍然显示。当在对话框边界之外触摸时,我可以轻松关闭对话框dialog.setCanceledOnTouchOutside(true);
但是,如果单击超出对话框的范围,我想做的是触发一个事件(例如,如果有人触摸主 Activity 上的按钮,它应该关闭对话框并同时触发该事件)。
我想知道如何解决我遇到的问题。
我有一个在活动中弹出的对话框。对话框没有覆盖整个屏幕,因此活动中的按钮仍然显示。当在对话框边界之外触摸时,我可以轻松关闭对话框dialog.setCanceledOnTouchOutside(true);
但是,如果单击超出对话框的范围,我想做的是触发一个事件(例如,如果有人触摸主 Activity 上的按钮,它应该关闭对话框并同时触发该事件)。
那时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()
以便在取消对话框时运行。
这个对我有用,,
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();
DialogFragment
您可以使用@silverTech的AlertDialog
答案:
override fun onDismiss(dialog: DialogInterface) {
yourMethod()
super.onDismiss(dialog)
}
或者
override fun onCancel(dialog: DialogInterface) {
yourMethod()
super.onCancel(dialog)
}
当在对话框外发生单击时,您可以使用OnCancelListener触发事件:
dialog.setOnCancelListener(new DialogInterface.OnCancelListener() {
@Override
public void onCancel(DialogInterface dialog) {
yourFunction();
}
});
如果您在自定义对话框类中,并且希望捕获“点击外部”事件 - 覆盖取消()。如果你想捕捉“对话框关闭”事件 - 覆盖dismiss()。我建议在 super.dismiss() 之前插入逻辑。科特林示例:
override fun dismiss() {
Utils.hideKeyboard(mContext, window)
super.dismiss()
}
它可在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() */
}
}
使用后退按钮命令返回上一个屏幕。
在扩展 DialogFragment 的类中使用覆盖方法 onCancel 。. .
@Override
public void onCancel(@NonNull DialogInterface dialog)
{
super.onCancel(dialog);
getParentFragment().getActivity().onBackPressed();
}
我发现所有其他答案都非常冗长和复杂,所以我使用了这种方法:
第 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;
}
}
);