Android:如何在触摸屏幕外部时关闭DatePicker DialogFragment?

4

我有一个工作的DatePickerFragment,它扩展了DialogFragment。在onCreateDialog()中设置了一个DatePickerDialog,然后尝试添加:

"picker.setCanceledOnTouchOutside(true);"

我正在使用Android 8.0 Oreo设备进行测试,当触摸DatePicker对话框外部时,没有任何反应。我使用androidx.appcompat.app.AppCompatActivity作为我的BaseActivity和androidx.fragment.app.DialogFragment用于DialogFragment;

代码:

@Override
public Dialog onCreateDialog(Bundle savedInstanceState) {
    super.onCreateDialog(savedInstanceState);

    DatePickerDialog picker = new DatePickerDialog(getActivity(),this,year,month,day);
    **picker.setCanceledOnTouchOutside(true);**
    return picker;

这是创建 Fragment 的 Activity 代码:

DatePickerFragment newFragment = new DatePickerFragment();
// tried the below also, with no luck
**newFragment.setCancelable(true);**
newFragment.show(getSupportFragmentManager(), "datePicker");

我也在DialogFragment中尝试了下面的代码,但仍然没有成功:
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
   ...
   getDialog().setCanceledOnTouchOutside(true);
   ... 
   }

并且:

@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
    if (getDialog() != null) {
        getDialog().setCanceledOnTouchOutside(true);
    }
    return super.onCreateView(inflater, container, savedInstanceState);
}    

我参考了这篇帖子以获取可能的答案:如何在点击对话框外部时关闭 DialogFragment?。我漏掉了什么?

你好,你能发布源代码来展示日期选择器对话框吗? - Vall0n
我已经创建了它,在onCreateDialog()中创建并显示在上方。你还需要找别的东西吗? - AJW
嗨@AJW,我指的是您调用DialogFragment的语句。类似于myDatePickerFragment.show(getSupportFragmenetManager(), "tag") - Vall0n
啊,好的,我现在会添加在上面。 - AJW
我认为我已经将getDialog().setCanceledOnTouchOutside()放在我的片段的onStart中,并且对我很有效。 如果这不起作用,我建议您在DatePickerFragment中使用isCancelable进行调试。 另外,您是否在对话框中使用了自定义布局? - Saurabh
显示剩余3条评论
5个回答

2
如果您想要关闭扩展DialogFragment的对话框,请在onCreateView中编写以下代码:

setCancelable(true);

当您点击外部时,对话框将关闭。

示例代码:

@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
     setCancelable(true);
     return super.onCreateView(inflater, container, savedInstanceState);
}

我也尝试在DialogFragment中使用以下代码,但是没有成功:@Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { ... getDialog().setCanceledOnTouchOutside(true); ... } - AJW
仅返回翻译后的文本:不包括getdalog()。这只是一行代码。我将编辑我的答案并提供使用示例。 - Rembulan Moon
我正在对话框中使用DatePicker。如何获取“R.layout.dialog_cari_barang”的ID,以便我知道要充当视图的内容?没有带有DatePicker ID的XML文件。 - AJW
答案得到了赞同、采纳并获得了悬赏。关键在于使用onCreateView()和inflater。在您的代码答案中,"return super.onCreateView(inflater, container, savedInstanceState);"是什么意思? - AJW
为什么你不直接使用DatePickerDialog而是使用对话框片段? - Rembulan Moon
显示剩余2条评论

1

你尝试将对话框设置为可取消吗?

picker.setCancelable(true);

我还没有尝试过,我会试一下。除了“setCanceledOnTouchOutside(true);”之外,我还需要设置其他内容吗?还是只需要单独使用setCancelable()方法即可? - AJW
没有成功。我尝试了单独使用setCancelable(),也尝试了同时添加“setCanceledOnTouchOutside(true);”,但都没有起作用。 - AJW
请尝试使用dialogFragment.setCancelable(true); - Fahad Alotaibi
你的意思是在创建DialogFragment的代码所在的Activity中添加吗? - AJW
在活动中添加“newFragment.setCancelable(true)”没有成功,在创建DatePickerFragment之后,在“newFragment.show...);”之前。 - AJW
你能向我展示你创建的 Dialog Fragment 类吗? - Fahad Alotaibi

0
只需在您的对话框 onCreate 方法或构造函数中添加 setCancelable(true) 即可。

1
这不是和 @Fahad Alotaibi 一样的重复答案吗? - Tamir Abutbul

0

0

我认为我有类似的问题,但在我的情况下,对话框周围有一些阴影填充,我必须在靠近屏幕边缘的地方点击外部才能取消它。

这是我创建对话框的方式:

val calendar = Calendar.getInstance()
val year = calendar.get(Calendar.YEAR)
val month = calendar.get(Calendar.MONTH)
val day = calendar.get(Calendar.DAY_OF_MONTH)

val dpd = context?.let {
    DatePickerDialog(it, DatePickerDialog.OnDateSetListener { _, pickedYear, pickedMonth, pickedDay ->

         //do something with picked date.

    }, year, month, day)
}

dpd?.setCanceledOnTouchOutside(true)
dpd?.show()

尝试在您的实现中设置setCanceledOnTouchOutside(true),并尝试在靠近屏幕边缘的位置轻触以关闭它,可以在像Pixel 3 XL这样的大屏幕模拟器上测试。现在我知道这不是一个解决方案,您需要处理各种设备和屏幕尺寸,但我希望您确认您可能与我遇到了同样的问题:对话框在触摸外部时被取消,但这个“外部”并不那么明显,这可能是一个真正的问题。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接