I'm trying to prevent the user from entering an empty string into an EditTextPreference
(in the example, catName
). I use a OnPreferenceChangeListener
to detect when a change is made to the EditTextPreference
, and if there is a change and the string is blank, I use the EditTextPreference.setText()
command to reset to the old value. However, the new value doesn't show up properly if I reopen the EditTextPreference
in the GUI (the string is blank), and if I go back into the main app, I can verify that a blank value is being saved to the preferences.
I've verified that the if statement executes as expected, and that my parameter keeping track of the old name (oldCatName
) is updating as expected. I can even log the catName.getText()
value right before the setOnPreferenceChangeListener
finishes execution and I always see the value I expect (the new value set by the user, and when they enter a blank value, it properly resets to the old value). I'm not sure why setting the value to the EditTextPreference
isn't saving the value to the preferences file or updating the GUI.
public class SettingsActivity extends PreferenceActivity {
private String oldCatName;
private EditTextPreference catName;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
addPreferencesFromResource(R.xml.settings);
catName = (EditTextPreference) findPreference("cat_name");
oldCatName = catName.getText();
catName.setOnPreferenceChangeListener(new OnPreferenceChangeListener() {
@Override
public boolean onPreferenceChange(Preference preference, Object newVal) {
final String value = (String) newVal;
if (value.equals("")) {
catName.setText(oldCatName);
Log.e("new value", catName.getText());
}
else
oldCatName = value;
return true;
}
});
}
}
Thanks for the help! -Michael
Edit: A clarification. The logic in the if statement is executing correctly. The string value of the EditTextPreference
is even updating correctly. However, the value in the GUI if the user taps on the EditTextPreference
again does not correctly update, and the value in the app's shared preferences does not update correctly. It stays blank.
Finally found a solution by doing the following:
I used a SharedPreferences.OnSharedPreferenceChangeListener
instead of a Preference.OnPreferenceChangeListener
. The Preference.OnPreferenceChangeListener
looks for when the user changes a preference through the settings menu, and behaves before the change is committed to the preference data. The SharedPreferences.OnSharedPreferenceChangeListener
listens for changes to the actual preference data, not changes in the GUI, so it happens a little later. I noticed that in my first attempt, I could run setText()
immediately followed by getText()
on my EditTextPreference
object, and the getText()
value wouldn't match what I had just set the setText()
value to. I'm not sure why this happens, but waiting for the changes to actually commit before trying to run setText()
led to the correct response. Maybe it was a timing issue?
I run setPreferenceScreen(null)
and addPreferencesFromResource(R.xml.settings)
after updating the value in the EditTextPreference
. If I didn't do this, sometimes when the user would click on the EditTextPreference
again, the value in the field would appear blank even though the value in the settings file wasn't. This forces the settings page to, more or less, refresh itself.
The working code is below:
public class SettingsActivity extends PreferenceActivity {
private String oldCatName;
private EditTextPreference catName;
private SharedPreferences.OnSharedPreferenceChangeListener listener;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
addPreferencesFromResource(R.xml.settings);
createListener();
catName = (EditTextPreference) findPreference("cat_name");
oldCatName = catName.getText();
}
private void createListener() {
listener = new SharedPreferences.OnSharedPreferenceChangeListener() {
@Override
public void onSharedPreferenceChanged(
SharedPreferences sharedPreferences, String key) {
String value = sharedPreferences.getString("cat_name", "NULL");
if (value.equals("")) {
catName.setText(oldCatName);
setPreferenceScreen(null);
addPreferencesFromResource(R.xml.settings);
} else {
oldCatName = value;
}
}
};
PreferenceManager.getDefaultSharedPreferences(getApplicationContext())
.registerOnSharedPreferenceChangeListener(listener);
}
}