【问题标题】:How to check input in PreferenceActivity and prevent storing of invalid values?如何检查 PreferenceActivity 中的输入并防止存储无效值?
【发布时间】:2017-09-09 15:17:03
【问题描述】:

我为我的问题准备了一个完整简单的测试用例:ValidatePrefs app at GitHub:

点击右上角的“设置”图标,会显示SettingsActivity

我想通过从 onPreferenceChange 方法返回 truefalse 来验证 3 个 EditTextPreference 字段,但它从未被调用:

public class SettingsActivity extends PreferenceActivity implements Preference.OnPreferenceChangeListener {
    private static final String TAG = SettingsActivity.class.getSimpleName();

    public static final String ADDRESS   = "address";
    public static final String USERNAME  = "username";
    public static final String PASSWORD  = "password";

    @Override
    public void onCreate(Bundle savedInstanceBundle) {
        super.onCreate(savedInstanceBundle);
        addPreferencesFromResource(R.xml.settings);
    }

    @Override
    public boolean onPreferenceChange(Preference preference, Object value) {    
        if (! (preference instanceof EditTextPreference)) {
            return false;
        }

        EditTextPreference editTextPreference = (EditTextPreference)preference;
        String key = editTextPreference.getKey();
        String text = editTextPreference.getText();

        if (key == null || key.isEmpty() || text == null || text.isEmpty()) {
            return false;
        }

        switch (key) {
            case ADDRESS: {
                try {
                    new URI(text);
                } catch (URISyntaxException ex) {
                    ex.printStackTrace();
                    return false;
                }
                return true;
            }

            case USERNAME: {
                return text.length() > 0;
            }

            case PASSWORD: {
                return text.length() > 0;
            }
        }

        return false;
    }
}

更新:

SettingsActivity 中添加findPreferencesetOnPreferenceChangeListener 调用后,方法onPreferenceChange 最终被调用:

@Override
public void onCreate(Bundle savedInstanceBundle) {
    super.onCreate(savedInstanceBundle);
    addPreferencesFromResource(R.xml.settings);

    EditTextPreference address = (EditTextPreference) findPreference(ADDRESS);
    EditTextPreference username = (EditTextPreference) findPreference(USERNAME);
    EditTextPreference password = (EditTextPreference) findPreference(PASSWORD);

    address.setOnPreferenceChangeListener(this);
    username.setOnPreferenceChangeListener(this);
    password.setOnPreferenceChangeListener(this);
}

但是我仍然无法验证和防止保存错误数据,因为 text 变量包含 old 值。

您可以在下面的调试器屏幕截图中看到它 - 我输入了一个空字符串的新(无效)值,但变量 text 仍然包含 user1 值:

更新 2:

好的,我错误地检查了存储在 Preference 中的旧值,我应该查看作为第二个参数传递给 onPreferenceChange 方法的新值。这里是我SettingsActivity中方法的固定版本:

@Override
public boolean onPreferenceChange(Preference preference, Object obj) {
    if (!(preference instanceof EditTextPreference && obj instanceof String)) {
        return false;
    }

    EditTextPreference editTextPreference = (EditTextPreference)preference;
    String key = editTextPreference.getKey();
    String oldValue = editTextPreference.getText();
    String newValue = String.valueOf(obj);

    Log.d(TAG, String.format("key %s, value %s -> %s", key, oldValue, newValue));

    // TODO validate the newValue and return true or false

【问题讨论】:

  • 也许使用 TextWatcher

标签: android sharedpreferences android-preferences preferenceactivity android-sharedpreferences


【解决方案1】:

但是该方法永远不会被调用。

在我看来您忘记注册setOnPreferenceChangeListener(),这就是没有调用回调的原因。

【讨论】:

  • 是的,但是在我的应用程序中的哪里调用该方法?
  • 查看this问题中的用法。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-06-12
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-08-24
相关资源
最近更新 更多