问题
I want to validate an EditTextPreference
value to be inside a specific int
range (lets say 1 to 22). The only part that I could validate was the inputType
(number only) with the following xml declaration in the prefs.xml file.
android:inputType="number"
The second thing that I did is to write the following code in the ListSettings
activity.
public class ListSettings extends PreferenceActivity implements OnSharedPreferenceChangeListener{
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
addPreferencesFromResource(R.xml.prefs);
SharedPreferences sp = PreferenceManager.getDefaultSharedPreferences(this);
sp.registerOnSharedPreferenceChangeListener(this);
}
public void onSharedPreferenceChanged(SharedPreferences sp, String key) {
String value = sp.getString(key, null);
int intZoomValue = Integer.parseInt(value);
if (intZoomValue < 1 || intZoomValue > 22) {
Intent intent = new Intent().setClass(this, dialog.class);
// I want to call the dialog activity here...
}
}
and the dialog.class is the following:
public class dialog extends Activity {
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
AlertDialog.Builder builder = new AlertDialog.Builder(this);
builder.setMessage("Please enter a value between 1-22!");
builder.setCancelable(true);
AlertDialog alert = builder.create();
alert.show();
}
}
What I want to achieve is to call the dialog.class
(the alert dialog box) whenever the user enters a value not in the range 1-22.
I can't really understand how to validate with the proper way.
回答1:
It might be more user-friendly to just clamp the value to the permitted range if an invalid value is entered, and notify the user with a Toast that you have done so.
If your range is small, such as 1-22, then you may even consider using a Spinner
instead of an EditText
so that the user can't enter an invalid value in the first place.
回答2:
This is what I did:
EditTextPreference pref = (EditTextPreference) findPreference(this.getString(R.string.my_setting_key));
pref.getEditText().setFilters(new InputFilter[]{
new InputFilter (){
@Override
public CharSequence filter(CharSequence source, int start, int end, Spanned dest, int dstart, int dend) {
try {
int input = Integer.parseInt(dest.toString() + source.toString());
if (input<MAX_VALUE && input >0)
return null;
} catch (NumberFormatException nfe) { }
return "";
}
}
});
So the trick is that you can get and EditText from your EditTextPreference by using:
pref.getEditText()
then you can set a filter. The filter should return null when everything is ok and an empty string when the char the user entered would make the text invalid.
See also here
回答3:
You could use setPositivteButton and validate the input once the user hits Okay, if not okay, repop the dialog.
回答4:
The InputFilter solution does not work, especially with selectAllOnFocus. If you cannot use the suggested picker/spinner alternative, for example, when you want to enforce a minimum but not a maximum, you can disable the OK button when the value is invalid like this:
public static void setNumberRange(final EditTextPreference preference,
final Number min, final Number max) {
setNumberRange(preference, min, max, false);
}
public static void setNumberRange(final EditTextPreference preference,
final Number min, final Number max,
final boolean allowEmpty) {
preference.getEditText().addTextChangedListener(new TextWatcher() {
@Override
public void beforeTextChanged(CharSequence s, int start, int count, int after) {
}
@Override
public void onTextChanged(CharSequence s, int start, int before, int count) {
}
@Override
public void afterTextChanged(final Editable s) {
Dialog dialog = preference.getDialog();
if (dialog instanceof AlertDialog) {
Button button = ((AlertDialog) dialog).getButton(DialogInterface.BUTTON_POSITIVE);
if (allowEmpty && s.length() == 0) {
button.setEnabled(true);
return;
}
try {
if (min instanceof Integer || max instanceof Integer) {
int input = Integer.parseInt(s.toString());
button.setEnabled((min == null || input >= min.intValue()) && (max == null || input <= max.intValue()));
} else if (min instanceof Float || max instanceof Float) {
float input = Float.parseFloat(s.toString());
button.setEnabled((min == null || input >= min.floatValue()) && (max == null || input <= max.floatValue()));
} else if (min instanceof Double || max instanceof Double) {
double input = Double.parseDouble(s.toString());
button.setEnabled((min == null || input >= min.doubleValue()) && (max == null || input <= max.doubleValue()));
}
} catch (Exception e) {
button.setEnabled(false);
}
}
}
});
}
This allows you to specify minimum and/or maximum values as Integer, Float or Double (pass null for unbounded). Optionally you can allow/disallow empty values. (Values invalid initially are accepted.)
来源:https://stackoverflow.com/questions/9354511/how-to-validate-an-edittextpreference-value-for-a-specific-int-range