Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

InputFilter on EditText cause repeating text

I'm trying to implement an EditText that limits input to Capital chars only [A-Z0-9] with digits as well.

I started with the InputFilter method from some post.But here I am getting one problem on Samsung Galaxy Tab 2 but not in emulator or Nexus 4.

Problem is like this :

  1. When I type "A" the text shows as "A" its good
  2. Now when I type "B" so text should be "AB" but it gives me "AAB" this looks very Strange.

In short it repeats chars

Here's the code I'm working with this code :

public class DemoFilter implements InputFilter {

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

        if (source.equals("")) { // for backspace
            return source;
        }
        if (source.toString().matches("[a-zA-Z0-9 ]*")) // put your constraints
                                                        // here
        {
            return source.toString().toUpperCase();
        }
        return "";
    }
}

XML file code :

<EditText
    android:id="@+id/et_licence_plate_1"
    android:layout_width="0dp"
    android:layout_height="wrap_content"
    android:layout_weight="3"
    android:hint="0"
    android:imeOptions="actionNext"
    android:inputType="textNoSuggestions"
    android:maxLength="3"
    android:singleLine="true"
    android:textSize="18px" >
</EditText>

I'm totally stuck up on this one, so any help here would be greatly appreciated.

like image 980
sam_k Avatar asked Aug 30 '13 09:08

sam_k


2 Answers

The problem of characters duplication comes from InputFilter bad implementation. Rather return null if replacement should not change:

@Override
public CharSequence filter(CharSequence source, int start, int end, Spanned dest, int dstart, int dend) {
    boolean keepOriginal = true;
    StringBuilder sb = new StringBuilder(end - start);
    for (int i = start; i < end; i++) {
        char c = source.charAt(i);
        if (isCharAllowed(c)) // put your condition here
            sb.append(c);
        else
            keepOriginal = false;
    }
    if (keepOriginal)
        return null;
    else {
        if (source instanceof Spanned) {
            SpannableString sp = new SpannableString(sb);
            TextUtils.copySpansFrom((Spanned) source, start, end, null, sp, 0);
            return sp;
        } else {
            return sb;
        }           
    }
}

private boolean isCharAllowed(char c) {
    return Character.isUpperCase(c) || Character.isDigit(c);
}
like image 178
Kamil Seweryn Avatar answered Sep 20 '22 11:09

Kamil Seweryn


I've run into the same issue, after fixing it with solutions posted here there was still a remaining issue with keyboards with autocomplete. One solution is to set the inputType as 'visiblePassword' but that's reducing functionality isn't it?

I was able to fix the solution by, when returning a non-null result in the filter() method, use the call

TextUtils.copySpansFrom((Spanned) source, start, newString.length(), null, newString, 0);

This copies the auto-complete spans into the new result and fixes the weird behaviour of repetition when selecting autocomplete suggestions.

like image 22
kassim Avatar answered Sep 18 '22 11:09

kassim