Search code examples
androidandroid-input-filter

InputFilter fails to make first character keep uppercase after dots character


Cannot understand why when user input bachelor format like "B.Com".

I want to get "B.com" - c letter is lower case.

But I'm getting: "B.Com" - C letter is capital

Here is my code:

InputFilter value = new InputFilter() {
    @Override
    public CharSequence filter(CharSequence source, int start, int end, Spanned spanned, int dstart, int dend) {
        for(int i = start; i < end; i++) {
            String letterOne = source.subSequence(0,1).toString().toUpperCase();
            if(Character.toString(source.charAt(i)).matches("[a-zA-Z.? ]*")) {
                return source.subSequence(0,1).toString().toUpperCase()+source.subSequence(1,end).toString().toLowerCase();
            }
            return letterOne+source.subSequence(1,end).toString().toLowerCase();
        }
        return null;
    }
};

Solution

  • your current code in for statement may be reduced

    String letterOne = source.subSequence(0,1).toString().toUpperCase();
    if(Character.toString(source.charAt(i)).matches("[a-zA-Z.? ]*"))
    {
        return source.subSequence(0,1).toString().toUpperCase()+source.subSequence(1,end).toString().toLowerCase();
    }
    return letterOne+source.subSequence(1,end).toString().toLowerCase();
                
    

    inside if statement you have source.subSequence(0,1).toString().toUpperCase(), which is exacly same as letterOne, so we can reduce some code

    String letterOne = source.subSequence(0,1).toString().toUpperCase();
    if(Character.toString(source.charAt(i)).matches("[a-zA-Z.? ]*"))
    {
        return letterOne+source.subSequence(1,end).toString().toLowerCase();
    }
    return letterOne+source.subSequence(1,end).toString().toLowerCase();
    

    now it is clearly visible that if statement contains same return as last return in method, so it may be reduced again to:

    String letterOne = source.subSequence(0,1).toString().toUpperCase();
    return letterOne + source.subSequence(1,end).toString().toLowerCase();
    

    in above code you are not using i at all, so whole for statement is useless and filter may by shorted to:

    @Override
    public CharSequence filter(CharSequence source, int start, int end,
            Spanned spanned, int dstart, int dend) {
        if (start <= end) return null;
        String letterOne = source.subSequence(0,1).toString().toUpperCase();
        return letterOne + source.subSequence(1,end).toString().toLowerCase();
    }
    

    there is no .-present checking code, no uppercasing any other letter than first... you are always returning same String as source with first letter uppercased and all other lowercased

    you may try to use indexOf method for checking if dot is present in whole String sourceAsString (convert from CharSequence source), if yes then use split method for making array with two Strings - make first letter uppercase in both words and join them String properlyFormatted = firstWord + "." + secondWord;

    PS. be aware that split method takes REGEX as param and "." in REGEX means "any letter", so use escaping like this: split("\\.")