Indeed, quite simple, but still.

Limiting character amount

The first goal was to limit the amount of characters someone can type in an EditText. Well, this sounds easy and it is. You can set a filter, like so:

editText.setFilters(new InputFilter[]{
         new InputFilter.LengthFilter(MAX_SIZE)
});

Limiting to a certain value

Now to implement this for the setting that stops you from asking for a million pictures to be downloaded.

To be clearer: I have a preference that lets you set the amount of pictures you can download. You should be able to write only numbers* here.. I’ve done this, more or less inelegantly, with the “android:digit” attribute in the xml:

<EditTextPreference
       android:title="Max Amount"
       android:summary="The more, the heavier. Default = 12"
       android:key="viewMax"
       android:defaultValue="12"
       android:digits="0123456789"/>

* no, we’re not entering the amount in HEX.

This works OK, but you can type in a lot of 9’s if you want. That’s no good.

Now to add another LengthFilter is only applicable for numbers  up to (10^y)-1, e.g. up to 999: a LengthFilter(3) will of course limit you to 3 characters, not to an int of max 3.

I have not found a filter for the maximum value, as the standard InputFilter gives us “ALLCAPS” and the previously used LengthFilter. I think the cleanest method might be to write an InputFilter, but it’s rather easy to fix without one, using an OnSharedPreferenceChangeListener.

Simple summary of how to limit an edittext to a certain value

We can add a lot of Listeners, that trigger on a lot of different moments, this is just an example. The moment of warning might be a bit late (after having set the value), but as a proof-of-concept:

Implement OnSharedPreferenceChangeListener

Whenever you’ve changed the preference, trigger a function to check if everything is sane. The activity implements OnSharedPreferenceChangeListener, so you can do this:

getPreferenceScreen().getSharedPreferences()
              .registerOnSharedPreferenceChangeListener(this);

The Listener

Add the listener. It will check for the set value, and correct it if it’s not sane.

public void onSharedPreferenceChanged(SharedPreferences sharedPreferences,
		String key) {
  if ("yourPrefName".equals(key)) {
    String valueString = sharedPreferences.getString(key, "");
    int value = Integer.parseInt(valueString);
    if(value > MAX_VALUE){
	EditTextPreference p = (EditTextPreference) findPreference(key);
	p.setText(""+MAX_VALUE);
	Toast t = Toast.makeText(this,"Maximum amount limited to "+MAX_VALUE, Toast.LENGTH_SHORT);
	t.show();
    }else if(value < MIN_VALUE){
	EditTextPreference p = (EditTextPreference) findPreference(key);
	p.setText(""+MIN_VALUE);
	Toast t = Toast.makeText(this,"Minimum amount limited to "+MIN_VALUE, Toast.LENGTH_SHORT);
	t.show();
    }
}

This means that you CAN enter numbers that are too high or too low, but at least you’ll get a message saying you’ve failed, and the preference will remain something sane.

Bonus: a filter on an EditTextPreference

Now for a quick bonus. I was annoyed at first why you cannot simple add a filter to your EditTextPreference like you would with an EditText

yourEditTextPreference.setFilters(yourFilters);

This is because the input you’re getting for a preference actually is an EditText, and you’ve got to find it. Short story even shorter: get the EditText from the EditTextPreference. Duh :)

yourEditTextPreference.getEditText().setFilters(yourFilters);

Now I’ll see how fun it is to write a real filter. Why not?

4 comments on Simple EditText limitations

  1. Thomas says:

    Entering numbers in a text field on a mobile device is a hassle. Android doesn’t do a very good job at this: e.g. why do I still get the full qwerty keyboard if all I can type is digits?

    For hour/minute selection, the iPhone has a circular scrollable list, kind of like a slot machine. For small values, this works well.

    It seems that, in your case, the exact number doesn’t really matter… so maybe you could present some radio buttons instead (e.g. 10, 20, 50, 100)?

    My two cents :)

  2. ennaN says:

    That’s a good thought, and that’s what is the case in the choice for #comments and #notifications.

    The fact that I’m not doing this here is that i’m not really sure what we want: for the gridview (that i’m sure you remember ;) ) only values 12 and 24 would be really usable, but for the listview there’s all sorts of possibilities.

    But the methods in this post aren’t really ideal for AndroBlip, I agree :D Sharing them anyway was more of a braindump.

    By the way: you should be able to get the ‘numbers only’ field? I’ve seen this, although I’ve not checked it out, so I don’t know how/if you can force this…

  3. Jisha says:

    You can get the numbers only field by setting the attribute “android:inputType=number” to the EditText.