InputFilter removes whole text

985 Views Asked by At

I entered 3 alphabet character android clears input. I expected to remove last , 3rd character, not full text

enter image description here

update , removed regex regarding comment below and still same result

private final Integer mAlphabetCount = 2;

@Override
public CharSequence filter(CharSequence source, int start, int end, Spanned dest, int dstart, int dend) {

    String text = createResultString(source, start, end, dest, dstart, dend);

    if (text.length() <= mAlphabetCount) {
        for (int i = start; i < end; i++) {
            if (!Character.isLetter((source.charAt(i)))) {
                return "";
            }
        }
        return null;
    }

    char[] digit = text.substring(2).toCharArray();
    for (char c : digit) {
        if (!Character.isDigit(c)) {
            return "";
        }
    }

    return source;
}

private String createResultString(CharSequence source, int start, int end, Spanned dest, int dstart, int dend) {
    String sourceString = source.toString();
    String destString = dest.toString();
    return destString.substring(0, dstart) + sourceString.substring(start, end) + destString.substring(dend);
}
2

There are 2 best solutions below

3
Alex Sveshnikov On

UPDATED

First of all you need to decide what you want to happen in case of wrong user input. For example, the user already entered "AB" and now tries to enter "C". Do you want to discard the "C"? Do you want the input field to become "BC"? Let's say you want to discard the "C".

Check if source is an instance of Spanned. If so, then you cannot just send back an empty String if the input is invalid, or it will erase the textbox (this is happening to you now). You need to extract the correct part from the source and send it back. Since we decided to just discard all letters after the first 2 you can try to match source against ^([a-zA-Z]{0,2})(?:[^\d]*)(\d{0,7}). Then send back the result composed of matching group 1 + group 2, i.e. first 2 letters + first 7 digits.

If source is not an instance of Spanned you can check if dest + source matches ^[a-zA-Z]{0,2}\d{0,7}$. If yes, send back null, otherwise discard the input - send back an empty string.

0
Nininea On

Here is all I need, actually there are no need to use regex, but it will work the same way. answer reference

public CharSequence filter(CharSequence source, int start, int end, Spanned dest, int dstart, int dend) {
    if (source instanceof SpannableStringBuilder) {
        SpannableStringBuilder sourceAsSpannableBuilder = (SpannableStringBuilder) source;
        for (int i = end - 1; i >= start; i--) {
            char currentChar = source.charAt(i);
            if (i < mAlphabetCount) {
                if (!Character.isLetter(currentChar)) {
                    sourceAsSpannableBuilder.delete(i, i + 1);
                }
            } else {
                if (!Character.isDigit(currentChar)) {
                    sourceAsSpannableBuilder.delete(i, i + 1);
                }
            }
        }
        return source;
    } else {
        StringBuilder filteredStringBuilder = new StringBuilder();
        for (int i = start; i < end; i++) {
            char currentChar = source.charAt(i);
            if (dest.length() < mAlphabetCount) {
                if (Character.isLetter(currentChar)) {
                    filteredStringBuilder.append(currentChar);
                }
            } else {
                if (Character.isDigit(currentChar)) {
                    filteredStringBuilder.append(currentChar);
                }
            }
        }
        return filteredStringBuilder.toString();
    }
}