There's never any point in examining dest
alone in an InputFilter
; that's what's already present in the field. Change the regular expression match to be against source
and it would be appropriate if you only wanted to check that certain characters were accepted into the field. However, you want to check field formatting, not just filter the input on a character-by-character basis. This is much more complex.
Every time the user makes a change to the contents of tempEditText
, the system calls your filter's filter
method before the change is actually made. It passes the current field contents and the proposed change (which can be insert/append, delete, or replace). The change is represented by a source CharSequence source
(the characters—if any—to be added to the field), range start and end indexes within the source (the range is not necessarily all of source
), a Spanned dest
(the current field contents before the change) and range dstart and dend indexes within dest
that are proposed to be replaced by the indicated source
range.
The job of filter
is to modify the change (if necessary) and return a CharSequence
to use (in its entirety) in place of source
(or null
to go ahead and use source
). Rather than checking dest
as you are now doing, you will need to check whether the change will result in an acceptable field. To do this, you will need more complex logic. (Note, in particular, that the new character(s) may be intended for insert somewhere other than at the end; also, filter
will be called when the user is deleting characters as well as adding them.)
It may be easier to implement a TextWatcher
. In it's beforeTextChanged
method, you can record the current contents and in it's afterTextChanged
method, you can check (using a regular expression) whether the contents are acceptable and, if not, restore the before-the-change contents. (Make sure, though, that the text before the change was acceptable. If it isn't, substitute something acceptable—like clearing the field. Otherwise your code will go into an infinite loop because the TextWatcher
is going to be invoked again when you correct the field contents.)
You also have an error in your regular expression: it allows a leading zero. Here's an improved version that fixes this problem (and removes one set of unnecessary parentheses):
"^([1-9][0-9]{0,2})?(\.[0-9]?)?$"
(As an aside: you can use \d
instead of [0-9]
.)
EDIT
Here's my edit of your edit:
weightEditText.addTextChangedListener(new TextWatcher()
{
private static final Pattern sPattern
= Pattern.compile("^([1-9][0-9]{0,2})?(\.[0-9]?)?$");
private CharSequence mText;
private boolean isValid(CharSequence s) {
return sPattern.matcher(s).matches();
}
@Override
public void onTextChanged(CharSequence s, int start, int before, int count){
}
@Override
public void beforeTextChanged(CharSequence s, int start, int count,
int after){
mText = isValid(s) ? new CharSequence(s) : "";
}
@Override
public void afterTextChanged(Editable s)
{
if (!isValid(s))
{
weightEditText.setText(mText);
}
mText = null;
}
});