防止对话片段在单击外部/后退按钮时关闭,并显示一条要求确认的消息



我有一个允许用户输入长消息的DialogFragment。默认情况下,如果用户在 DialogFragment 或后退按钮外部单击,对话框将关闭,用户输入将丢失。

如果我使用"this.isCancelable = false",它会完全阻止后退按钮/外部单击触发,这是我不想要的。

相反,我希望出现一条弹出消息,其中包含"您确定要放弃更改吗",并且仅在用户单击"是"时才关闭 DialogFragment。我应该怎么做?

编辑:也试图用标志解决这个问题,但仍然有问题。

添加到 DialogFragment 的 "override fun OnResume((">

//FLAG_WATCH_OUTSIDE_TOUCH requires FLAG_NOT_TOUCH_MODAL to work
dialog?.window?.addFlags(
WindowManager.LayoutParams.FLAG_WATCH_OUTSIDE_TOUCH
)
dialog?.window?.addFlags(
WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL
)
dialog?.window?.decorView?.setOnTouchListener { v, event ->
if (event.action == MotionEvent.ACTION_OUTSIDE) {
//action to show a message
}
true
}

这种方法的问题是由于FLAG_NOT_TOUCH_MODAL,我现在可以单击对话框后面的项目,这会弄乱导航控制器并破坏应用程序。是否可以监视MotionEvent.ACTION_OUTSIDE,但阻止对话框之外的任何实际点击?

您可以将setCanceledOnTouchOut布尔值设置为 true,并对事件使用以下方法。

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 方法中显示您希望用于用户确认的 Toast 或对话框。

希望这有帮助!

1 为对话框的窗口属性设置标志FLAG_NOT_TOUCH_MODAL

Window window = this.getWindow();
window.setFlags(WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL,
WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL);

2 向 Windows 属性添加另一个标志,FLAG_WATCH_OUTSIDE_TOUCH - 此标志用于对话框在其可见区域之外接收触摸事件。

3 覆盖对话框的触摸事件((并检查操作类型。 如果操作类型为"MotionEvent.ACTION_OUTSIDE"表示用户正在对话框区域之外进行交互。因此,在这种情况下,您可以打开另一个对话框进行用户确认。

public boolean onTouchEvent(MotionEvent event)  
{  
if(event.getAction() == MotionEvent.ACTION_OUTSIDE){  
System.out.println("TOuch outside the dialog");  
this.dismiss();  
}  
return false;  
}  

找到了解决方案,归功于@Unknownweirdo,如何在对话框外单击关闭对话框?

Kotlin 代码:

override fun onResume() {
super.onResume()
dialog?.window?.addFlags(
WindowManager.LayoutParams.FLAG_WATCH_OUTSIDE_TOUCH
)
dialog?.window?.decorView?.setOnTouchListener { v, event ->
if (event.action == MotionEvent.ACTION_DOWN) {
val dialogBounds = Rect()
v.getHitRect(dialogBounds)
if (!dialogBounds.contains(event.x.toInt(), event.y.toInt())) {
// You have clicked the grey area
logicToConfirmDiscardingChange()
false // stop activity closing
}
}
true
}
}

相关内容

最新更新