How to validate an EditTextPreference value for a specific int range

拥有回忆 提交于 2019-12-06 09:15:13

问题


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

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!