InputFilter is triggered at the moment of replacing some substring of some kind [under] string. And the task is to believe the input, so as not to let enter invalid characters. For example, you can come up with a regular (a shorter version) that will skip the incremental input, i.e. give enter character by character. Or in the case of simple input, as in the question, simply check the relevant ranges ...
With regulars, for example, like this:
public class TimeFilter implements InputFilter { private final Pattern mPattern; public TimeFilter(Pattern pattern){ this.mPattern = pattern; } @Override public CharSequence filter(CharSequence source, int start, int end, Spanned dest, int dstart, int dend) { // Получаем результат ввода как замену вырезанного из dest на source // при обычном вводе dstart==dend - позиция в которой произошел ввод String result = dest.subSequence(0, dstart) + source.toString() + dest.subSequence(dend, dest.length()); Matcher matcher = mPattern.matcher(result); // Если результат не соответствует регулярке, возвращаем кусок, // который удалился бы, т.е. то, что заменили в dest. // При обычном вводе, возвращается пустая строка // Или оригинальное выделение, если что-то было выделено if (!matcher.matches()) return dest.subSequence(dstart, dend); // Ввод соответствует регулярке return null; } }
For hours, a filter like this (in regulars is not very strong, but it seems to work):
new TimeFilter(Pattern.compile("^(([0-1]([0-9]){0,1})?|(2([0-3]){0,1})?)$"));
For minutes like this:
new TimeFilter(Pattern.compile("^([0-5]([0-9]){0,1})?$"));
If just checking ranges, then
... if(result.isEmpty()) return null; try { int v = Integer.parseInt(result); if(v>23 || v<0) return dest.subSequence(dstart, dend); } catch (NumberFormatException e) { return dest.subSequence(dstart, dend); } ...
Deal with leading zeros yourself.