如何为标准对话框 PreferenceFragmentCompat 设置 Cancelable(false)

How to setCancelable(false) for standard dialog PreferenceFragmentCompat

我正在使用 PreferenceFragmentCompat 来显示和设置 SharedPreferences。这一切都很好。但是,我的日志中不断出现“W/InputEventReceiver:尝试完成输入事件但输入事件接收器已被处理。”,因为 PreferencesFragmentCompat 使用的标准对话框似乎没有在其 showDialog 方法中使用 .setCancelable(false) 。我想我可以构建自己的自定义对话框,但仅仅解决这个小问题似乎有点矫枉过正。有什么方法可以简单地覆盖方法吗?

更新:

将它添加到我的 PreferencesFragmet 中就足够了(删除了 MultiSelectListPreferenceDialogFragmentCompat,因为我不使用它)

@Override
public void onDisplayPreferenceDialog(Preference pref) {
    DialogFragment dialogFragment = null;
    String DIALOG_FRAGMENT_TAG = "androidx.preference.PreferenceFragment.DIALOG";

    if (pref instanceof EditTextPreference) {
        dialogFragment = EditTextPreferenceDialogFragmentCompat.newInstance(pref.getKey());
    } else if (pref instanceof ListPreference) {
        dialogFragment = ListPreferenceDialogFragmentCompat.newInstance(pref.getKey());
    }

    if (dialogFragment != null) {
        dialogFragment.setTargetFragment(this, 0);
        dialogFragment.setCancelable(false); //adding this!
        if (this.getFragmentManager() != null) {
            dialogFragment.show(this.getFragmentManager(), DIALOG_FRAGMENT_TAG);
        }
    } else {
        super.onDisplayPreferenceDialog(pref);
    }
}

我整理了 PreferenceFramgnetCompat 源代码来解决这个问题。

不幸的是,您无法在没有回调或覆盖的情况下执行“.setCancelable(false)”以进行对话。

我会用回调来解释。

您应该在 activity 上实现 'PreferenceFragmentCompat.OnPreferenceDisplayDialogCallback' 接口,其中包含 PreferenceFragmentCompat 片段。

当用户按下 EditTextPreference、ListPreference 或 AbstractMultiSelectListPreference 中的一个首选项时,将执行 onPreferenceDisplayDialog 方法。

执行onPreferenceDisplayDialog方法时,您应该打开对话框。 幸运的是,有三种类型的对话框,Google 由 public 提供,因此您不需要为它们制作自定义对话框。

只需创建对话框实例并调用 setCancelable(false) 并显示它!

请参考以下代码。


class SettingsActivity : FragmentActivity(), PreferenceFragmentCompat.OnPreferenceDisplayDialogCallback {
        private val DIALOG_FRAGMENT_TAG = "android.support.v7.preference.PreferenceFragment.DIALOG"

        override fun onCreate(savedInstanceState: Bundle?) {
                super.onCreate(savedInstanceState)

                supportFragmentManager.beginTransaction()
                                .replace(android.R.id.content, SettingsFragment(), "setting_fragment").commit()
        }

        override fun onPreferenceDisplayDialog(caller: PreferenceFragmentCompat, preference: Preference?): Boolean {
                // check if dialog is already showing
                if (supportFragmentManager!!.findFragmentByTag(DIALOG_FRAGMENT_TAG) != null) {
                        return true
                }

                val f: DialogFragment
                if (preference is EditTextPreference) {
                        f = EditTextPreferenceDialogFragmentCompat.newInstance(preference.getKey())
                } else if (preference is ListPreference) {
                        f = ListPreferenceDialogFragmentCompat.newInstance(preference.getKey())
                } else if (preference is AbstractMultiSelectListPreference) {
                        f = MultiSelectListPreferenceDialogFragmentCompat.newInstance(preference.getKey())
                } else {
                        throw IllegalArgumentException("Tried to display dialog for unknown " + "preference type. Did you forget to override onDisplayPreferenceDialog()?")
                }

                f.setTargetFragment(supportFragmentManager.findFragmentByTag("setting_fragment"), 0)

                f.isCancelable = false // !! HERE !!

                f.show(supportFragmentManager!!, DIALOG_FRAGMENT_TAG)

                return true
        }
}