【问题标题】:Modifying a preference value in a PreferenceScreen by code通过代码修改 PreferenceScreen 中的首选项值
【发布时间】:2022-01-11 20:01:43
【问题描述】:

我在文档 herehere 之后有一个 PreferenceScreen。

其中一个选项是 SwitchPreferenceCompat,它在我的应用程序中执行一些有风险的工作,例如,定期发送敏感信息。这是简单的开关:

<SwitchPreferenceCompat
            app:key="SendInfoToServer"
            app:title="Send information on your device to our servers" />

我需要的是向用户提出这样的问题:

这将定期发送敏感信息 您的设备到我们的服务器。 您确定要启用此选项吗?

如果用户回答“是”,那么我希望 SwitchPreferenceCompat 被激活,否则不被激活。

我调查了一下,发现了这段代码:

    findPreference("SendInfoToServer").setOnPreferenceChangeListener(new Preference.OnPreferenceChangeListener() {
        @Override
        public boolean onPreferenceChange(Preference preference, Object newValue) {
            if((boolean) newValue == true){
                Toast("Activating this function will safe sensitive information");
            }
            return true;
        }
    });

但此消息只是向用户显示的警告消息。我想要实现的是提出一个问题。如果用户同意,则开关应打开,如果用户不同意,则开关应保持关闭。

关于如何做到这一点的任何想法。

【问题讨论】:

    标签: android androidx preferencescreen


    【解决方案1】:

    您可以使用isChecked 方法对其进行修改。这是一个使用您描述的弹出对话框执行此操作的示例。这使用onPreferenceChangeListener,如果该选项被禁用,它会显示一个对话框并为侦听器返回 false(因此首选项不会立即更新)。

    如果用户在对话框中选择了正确的选项,则使用isChecked 方法将其禁用。如果该选项被重新启用,该对话框将不会显示,只有在它被禁用时才会显示。

    如果您想在启用该选项时显示对话框,则可能会颠倒某些逻辑,但总体概念是相同的。关键是在显示对话框时返回 false 使其不会更改,然后如果用户确认要更改它,则稍后使用 isChecked 更改它。

    // replace this with getting the switch if you defined it in the XML
    val enableChecks = SwitchPreference(context)
    enableChecks.key = Constants.ENABLE_CHECKS
    enableChecks.title = getString(R.string.enable_checks)
    enableChecks.isPersistent = true
    
    
    enableChecks.onPreferenceChangeListener =
        Preference.OnPreferenceChangeListener { _, value ->
    
            val disabling = !(value as Boolean)
            if( disabling ) {
                SimpleDialogs.twoButton(
                    context,
                    title = getString(R.string.confirm_disable_check),
                    message = getString(R.string.confirm_disable_check_msg),
                    posButton = getString(R.string.disable),
                    negButton = getString(R.string.cancel),
                    onPos = {
                        // user confirmed they want to disable it, set to false
                        enableChecks.isChecked = false
                    },
                    onNeg = {
                        // user changed their mind, keep it true
                        enableChecks.isChecked = true
                    },
                    icon = SimpleDialogs.ICON_WARNING
                )
    
                // return false so the change isn't applied here if showing a dialog
                false
            }
            else {
                true
            }
        }
    
    appearanceCat.addPreference(enableChecks)
    

    【讨论】:

    • 非常感谢。我是 Java 用户(我太老了,不会学习 Kotlin)所以让我为 Java 用户写另一个答案。
    【解决方案2】:

    基于 Tyler V 答案的 Java 类似答案:

        SwitchPreferenceCompat oSwitchPreferenceCompat = findPreference("MyKey");
        oSwitchPreferenceCompat.setOnPreferenceChangeListener(new Preference.OnPreferenceChangeListener() {
            @Override
            public boolean onPreferenceChange(Preference preference, Object newValue) {
                if((boolean) newValue == false){
                    return true; //If the check is disabled we do not need to ask the user. In this case we allow the normal flow and let the system disable it. Returning "true" allows the System to disable it.
                }
                //Here the user is enabling the check, so we prompt to confirm it:
                AlertDialog.Builder builder = new AlertDialog.Builder(getContext());
                builder.setMessage("Are you sure you want to enable this?");
                builder.setPositiveButton("Yes", new DialogInterface.OnClickListener() {
                    public void onClick(DialogInterface dialog, int which) {
                        oSwitchPreferenceCompat.setChecked(true);
                    }
                });
                builder.setNegativeButton("No", new DialogInterface.OnClickListener() {
                    public void onClick(DialogInterface dialog, int which) {
                        oSwitchPreferenceCompat.setChecked(false);
                    }
                });
                builder.setCancelable(false);
                Dialog d = builder.create();
                d.show();
                return false;//returning false we are telling the System to not modify the check yet.
            }
        });
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-10-16
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多