0

我为我的 DialogFragment 定义了一个方法,它将弹出另一个(警报)对话框,我确认用户想要关闭 DialogFragment。如果是这种情况,那么我打电话给DialogFragment.dismiss(). 如果不是,则应该简单地忽略 DialogFragment 的解除,并且用户应该像以前一样返回到它。

此方法(例如confirmCancel())用于 DialogFragment 底部的“取消”按钮。由于我还希望在用户按下后退按钮或触摸 DialogFragment 外部时显示它,因此我将 confirmCancel 设置为它onCancelListener(当然,我也使用getDialog().setCanceledOnTouchOutside(true)过)。

这是代码confirmCancel()

public void confirmCancel()
{
    (new AlertDialog.Builder(getActivity())
             .setIcon(R.drawable.ic_baseline_warning_24)
             .setTitle("Discard changes")
             .setMessage("Are you sure you want to discard changes and go back?")
             .setPositiveButton("Yes", ( dialogInterface, i ) -> dismiss())
             .setNegativeButton("No", ( dialogInterface, i ) -> {})
             .show()).setCanceledOnTouchOutside(true);
}

这几乎可以完美地工作,除了当 AlertDialog 显示在屏幕上时,DialogFragment 已经被解除,并且在 AlertDialog 中采取的操作根本没有用。

所以我现在需要的是一种“取消”解除 DialogFragment 的方法,或者是在解除之前调用的方法。我该如何解决这个问题?

PS:getDialog().setCancelable(false)对我没有帮助,因为我确实希望取消对话;只是我希望它有条件地取消。

4

1 回答 1

1

既不DialogFragment也不Dialog提供在取消/关闭事件之前检查的条件,您可以设置。他们只提供在所述事件被触发后通知的侦听器,此时损害已经造成。

我已经梳理了源代码并确定他们没有办法强制它进入忽略第一个取消/关闭调用但仍然允许侦听器触发以便您可以捕获事件的状态,我认为反射会弄乱字段,但它变得混乱。我还尝试强制异常以创建无效状态,但是没有无效状态可以允许您想要的功能。

这是两个来源。

https://android.googlesource.com/platform/frameworks/base/+/master/core/java/android/app/Dialog.java

https://android.googlesource.com/platform/frameworks/support/+/refs/heads/androidx-activity-release/fragment/fragment/src/main/java/androidx/fragment/app/DialogFragment.java

您可以使用包含ActivityWindow来处理触摸事件并将它们发送回DialogFragment使用 a FragmentResultListener,即DialogFragment设置为不可取消并且当用户触摸外部时将其 Activity拾取并调用setFragmentResult以将其发送回DialogFragment. 这可能会或可能不会起作用,具体取决于对话框如何检测/接收外部触摸事件,它是消耗它们还是让它们通过,当它不可取消时。

到目前为止最简单的解决方案是复制上面的源代码,可能只是DialogFragment自己制作来解决这个问题。

或 或 或

我完全错过了最明显的解决方案。

于 2021-09-11T05:59:13.437 回答