43

What I want to do is I am working on a game of life program. I want to take the time delay and make it a preference, but I want to make it available for people to type in a specific time. The number can be in miliseconds or seconds.

However I'm a little stuck on how to proceed, I haven't been able to find a simple preference that already handles this, but there might be one. Is there an easy way to make this preference and confirm that the entered data is an integer or afloat?

Jon Limjap
  • 94,284
  • 15
  • 101
  • 152
Kinglink
  • 819
  • 1
  • 8
  • 14

5 Answers5

89

Use an EditTextPreference and set the input type to TYPE_CLASS_NUMBER. This will force the user to enter numbers and not letters.

EditTextPreference pref = (EditTextPreference)findPreference("preference_name");
pref.getEditText().setInputType(InputType.TYPE_CLASS_NUMBER);
Kevin Westwood
  • 7,739
  • 8
  • 38
  • 52
  • 10
    This one works and should be answer to this question. Although dot, coma and other values are displayed to user, the user **can not** insert them. So only input you receive from this is numeric. – Indrek Kõue Mar 23 '12 at 10:32
  • 33
    You can also use `android:inputType="number"` when working with XML. – tslocum Aug 20 '14 at 02:41
  • 4
    Note that this doesn't work anymore with the AndroidX libraries: `getEditText()` is not available anymore and the XML attributes don't work either: https://issuetracker.google.com/issues/37060038. However, one can still change settings on the EditText with `setOnBindEditTextListener` as mentioned by an other answer. – user905686 Jun 12 '21 at 17:40
39

You can also enforce it with the xml attribute android:numeric. The possible relevant values for this attribute are decimal and integer.

HRJ
  • 17,079
  • 11
  • 56
  • 80
  • 1
    `EditTextPreference` doesn't have parameter `numeric`. – Indrek Kõue Mar 23 '12 at 10:25
  • 8
    @SYLARRR It does. The `EditTextPreference` supports all attributes of `EditText`. And I am using this attribute in my project. – HRJ Mar 23 '12 at 12:42
  • 3
    This does work. http://stackoverflow.com/a/13425382/2291 has a slightly more descriptive comment about why this works and where it is documented. (TL;DR it barely is documented.) – Jon Adams Aug 14 '13 at 21:58
32

You can also do this directly in your preferences.xml. Something like this would work:

<EditTextPreference
    android:defaultValue="100"
    android:dialogTitle="@string/pref_query_limit"
    android:inputType="number"
    android:key="pref_query_limit"
    android:summary="@string/pref_query_limit_summ"
    android:title="@string/pref_query_limit" />
Jeshurun
  • 22,940
  • 6
  • 79
  • 92
  • 4
    If I do this, it still shows me a full keyboard and allows me to input letters, symbols, etc., which they break settings – Elliptica Jul 18 '18 at 18:39
17

If you are using a PreferenceActivity which you probably are, there is not one available.

You will need to do something like this:

    /**
 * Checks that a preference is a valid numerical value
 */
Preference.OnPreferenceChangeListener numberCheckListener = new OnPreferenceChangeListener() {

    @Override
    public boolean onPreferenceChange(Preference preference, Object newValue) {
        //Check that the string is an integer.
        return numberCheck(newValue);
    }
};

private boolean numberCheck(Object newValue) {
    if( !newValue.toString().equals("")  &&  newValue.toString().matches("\\d*") ) {
        return true;
    }
    else {
        Toast.makeText(ActivityUserPreferences.this, newValue+" "+getResources().getString(R.string.is_an_invalid_number), Toast.LENGTH_SHORT).show();
        return false;
    }
}


    @Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);

    //get XML preferences
    addPreferencesFromResource(R.xml.user_preferences);


    //get a handle on preferences that require validation
    delayPreference = getPreferenceScreen().findPreference("pref_delay");

    //Validate numbers only
    delayPreference.setOnPreferenceChangeListener(numberCheckListener);

}
jax
  • 37,735
  • 57
  • 182
  • 278
  • only issue is delayPreference isn't defined in the example (it's a Preference I know) Also this is code for inside the preference activity class, but seems to work well, thank you very much. – Kinglink Jul 14 '10 at 03:01
4

In Android Jetpack Preference things changed, to access EditText you have to access like this

val preference = findPreference<EditTextPreference>(getString(R.string.pref_numdefault_key))
preference?.setOnBindEditTextListener {
    it.inputType = InputType.TYPE_CLASS_NUMBER
}
Kirill Rakhman
  • 42,195
  • 18
  • 124
  • 148
dastan
  • 892
  • 10
  • 17