如何检查 PreferenceActivity 中的输入并防止存储无效值?
How to check input in PreferenceActivity and prevent storing of invalid values?
我已经为我的问题准备了一个完整而简单的测试用例:ValidatePrefs app at GitHub:
当您点击右上角的"Settings"图标时,会显示SettingsActivity。
我想通过从 onPreferenceChange
方法返回 true
或 false
来验证 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 中添加 findPreference
和 setOnPreferenceChangeListener
调用后,方法 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
仍然包含 old 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
However that method is never called.
看来你忘记注册了setOnPreferenceChangeListener()
,这就是回调没有被调用的原因。
我已经为我的问题准备了一个完整而简单的测试用例:ValidatePrefs app at GitHub:
当您点击右上角的"Settings"图标时,会显示SettingsActivity。
我想通过从 onPreferenceChange
方法返回 true
或 false
来验证 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 中添加 findPreference
和 setOnPreferenceChangeListener
调用后,方法 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
仍然包含 old 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
However that method is never called.
看来你忘记注册了setOnPreferenceChangeListener()
,这就是回调没有被调用的原因。