Android:带验证的onPreferenceChange

时间:2016-11-23 14:25:51

标签: android validation preferences

快速浏览:

我已经在一个示例项目中构建了与onPreferenceChanged一起使用的验证,该项目旨在测试设置以及它们如何保存等等。功能就在那里,并按照我的意愿工作。我希望能够将此功能转移到默认生成的SettingsActivity类中,因为它似乎提供了可靠的功能和扩展程序所需的标题。

我想要实现的代码本身就是下面提供的内容。很简单,我有一个检查,它决定是否需要执行特定的验证,如果是,它会附加特定的验证,否则它附加一个通用验证。 我认为这是一种hacky方法,如果可能的话,我希望有一种替代方法。

// Type of verification checking to attach
public void attachOnPreferenceChangedListener(Preference dsp_pref) {
    if (dsp_pref.getKey().equals("et_targetPref")) {
        attachTargetVerifier(dsp_pref);
    } else { // Any non verifier specific is given a generic listen with summary updater
        attachGenericVerifier(dsp_pref);
    }
}

private void attachGenericVerifier(Preference dsp_pref) {
    dsp_pref.setOnPreferenceChangeListener(new Preference.OnPreferenceChangeListener() {
        @Override
        public boolean onPreferenceChange(Preference preference, Object newValue) {
            updatePrefSummary(preference);
            return true;
        }
    });
}

private void attachTargetVerifier(Preference dsp_pref) {
    dsp_pref.setOnPreferenceChangeListener(new Preference.OnPreferenceChangeListener() {
        @Override
        public boolean onPreferenceChange(Preference preference, Object newValue) {
            Pattern dsl_pattern = Pattern.compile(URL_REGEX,Pattern.CASE_INSENSITIVE);
            Matcher dsl_matcher = dsl_pattern.matcher(newValue.toString());

            if (!dsl_matcher.matches()) {
                Toast.makeText(getActivity(), "Invalid URL.  Example: http://example.com/target", Toast.LENGTH_LONG).show();
            } else if (dsl_matcher.group(1).toLowerCase().endsWith("/target")) {
                Toast.makeText(getActivity(), "Preference Saved", Toast.LENGTH_LONG).show();
                updatePrefSummary(preference);
                return true;
            } else if(dsl_matcher.group(2) == null) {
                Toast.makeText(getActivity(), "URL must start with 'http://'", Toast.LENGTH_LONG).show();
            } else {

            }
            return false;
        }
    });
}

默认的SettingsActivity提供的只是一个简单而直接的OnPreferenceChange覆盖,这可能意味着验证检查需要在此集成,除非存在更优雅的方法,在这种情况下,我所有耳朵:

private static Preference.OnPreferenceChangeListener sBindPreferenceSummaryToValueListener = new Preference.OnPreferenceChangeListener() {
    @Override
    public boolean onPreferenceChange(Preference preference, Object value) {
        String stringValue = value.toString();

        if (preference instanceof ListPreference) {
            // For list preferences, look up the correct display value in
            // the preference's 'entries' list.
            ListPreference listPreference = (ListPreference) preference;
            int index = listPreference.findIndexOfValue(stringValue);

            // Set the summary to reflect the new value.
            preference.setSummary(
                    index >= 0
                            ? listPreference.getEntries()[index]
                            : null);

        } else if (preference instanceof RingtonePreference) {
            // For ringtone preferences, look up the correct display value
            // using RingtoneManager.
            if (TextUtils.isEmpty(stringValue)) {
                // Empty values correspond to 'silent' (no ringtone).
                preference.setSummary(R.string.pref_ringtone_silent);

            } else {
                Ringtone ringtone = RingtoneManager.getRingtone(
                        preference.getContext(), Uri.parse(stringValue));

                if (ringtone == null) {
                    // Clear the summary if there was a lookup error.
                    preference.setSummary(null);
                } else {
                    // Set the summary to reflect the new ringtone display
                    // name.
                    String name = ringtone.getTitle(preference.getContext());
                    preference.setSummary(name);
                }
            }

        } else {
            // For all other preferences, set the summary to the value's
            // simple string representation.
            preference.setSummary(stringValue);
        }
        return true;
    }
};

感谢任何关于如何做到这一点的建议,如果它不会变得无法管理

1 个答案:

答案 0 :(得分:0)

解决方案,对于那些感兴趣的人,虽然不完整,100%是将小验证块放在顶部,如果验证失败,则执行返回false:

private static Preference.OnPreferenceChangeListener sBindPreferenceSummaryToValueListener = new Preference.OnPreferenceChangeListener() {
    @Override
    public boolean onPreferenceChange(Preference preference, Object value) {
        String stringValue = value.toString();

        ///////////////////////////////////////////////////////////////////
        // Preference Validation Section
        ///////////////////////////////////////////////////////////////////

        // URL Check: http://whatev.er/targetstore
        if (preference.getKey().equals("connect_url")) {
            Pattern dsl_pattern = Pattern.compile(URL_REGEX,Pattern.CASE_INSENSITIVE);
            Matcher dsl_matcher = dsl_pattern.matcher(stringValue);

            if (dsl_matcher.matches() && // Match!
                    dsl_matcher.group(1).toLowerCase().endsWith("/targetstore")) { // Confirmed validity
                Toast.makeText(dsl_context, "Preference Saved", Toast.LENGTH_LONG).show();
            } else { // No match - don't save data.
                Toast.makeText(dsl_context, "Invalid URL.  Example: http://example.com/targetstore", Toast.LENGTH_LONG).show();
                return false; // Stops result from saving
            }
        }
        if (preference instanceof ListPreference) {
            //List Pref setSummary

        } else if (preference instanceof RingtonePreference) {
            //Ringtone Pref setSummary
        } else {
            // For all other preferences, set the summary to the value's
            // simple string representation.
            preference.setSummary(stringValue);
        }
        return true;
    }
};

加载设置时仍然存在问题,将显示“Preference Saved”提示。一些检查验证数据是否被读取和未设置可能有助于解决这个问题,但我不知道这样的检查。