error while trying editText.setSelection

-1

I am trying to apply a mask in my EditText, however when I try to enter a value beyond what is allowed I get the error:

05-20 17:17:23.943: E/AndroidRuntime(1399): FATAL EXCEPTION: main
05-20 17:17:23.943: E/AndroidRuntime(1399): java.lang.IndexOutOfBoundsException: setSpan (17 ... 17) ends beyond length 13
05-20 17:17:23.943: E/AndroidRuntime(1399):     at android.text.SpannableStringBuilder.checkRange(SpannableStringBuilder.java:934)
05-20 17:17:23.943: E/AndroidRuntime(1399):     at android.text.SpannableStringBuilder.setSpan(SpannableStringBuilder.java:527)
05-20 17:17:23.943: E/AndroidRuntime(1399):     at android.text.SpannableStringBuilder.setSpan(SpannableStringBuilder.java:520)
05-20 17:17:23.943: E/AndroidRuntime(1399):     at android.widget.SpellChecker$SpellParser.init(SpellChecker.java:308)
05-20 17:17:23.943: E/AndroidRuntime(1399):     at android.widget.SpellChecker.spellCheck(SpellChecker.java:149)
05-20 17:17:23.943: E/AndroidRuntime(1399):     at android.widget.TextView.updateSpellCheckSpans(TextView.java:7753)
05-20 17:17:23.943: E/AndroidRuntime(1399):     at android.widget.TextView.handleTextChanged(TextView.java:7620)
05-20 17:17:23.943: E/AndroidRuntime(1399):     at android.widget.TextView$ChangeWatcher.onTextChanged(TextView.java:7990)
05-20 17:17:23.943: E/AndroidRuntime(1399):     at android.text.SpannableStringBuilder.sendTextChange(SpannableStringBuilder.java:881)
05-20 17:17:23.943: E/AndroidRuntime(1399):     at android.text.SpannableStringBuilder.change(SpannableStringBuilder.java:389)
05-20 17:17:23.943: E/AndroidRuntime(1399):     at android.text.SpannableStringBuilder.change(SpannableStringBuilder.java:266)
05-20 17:17:23.943: E/AndroidRuntime(1399):     at android.text.SpannableStringBuilder.replace(SpannableStringBuilder.java:443)
05-20 17:17:23.943: E/AndroidRuntime(1399):     at android.text.SpannableStringBuilder.delete(SpannableStringBuilder.java:216)
05-20 17:17:23.943: E/AndroidRuntime(1399):     at android.text.SpannableStringBuilder.delete(SpannableStringBuilder.java:29)
05-20 17:17:23.943: E/AndroidRuntime(1399):     at android.text.method.BaseKeyListener.backspaceOrForwardDelete(BaseKeyListener.java:90)
05-20 17:17:23.943: E/AndroidRuntime(1399):     at android.text.method.BaseKeyListener.backspace(BaseKeyListener.java:45)
05-20 17:17:23.943: E/AndroidRuntime(1399):     at android.text.method.BaseKeyListener.onKeyDown(BaseKeyListener.java:151)
05-20 17:17:23.943: E/AndroidRuntime(1399):     at android.text.method.QwertyKeyListener.onKeyDown(QwertyKeyListener.java:352)
05-20 17:17:23.943: E/AndroidRuntime(1399):     at android.text.method.TextKeyListener.onKeyDown(TextKeyListener.java:132)
05-20 17:17:23.943: E/AndroidRuntime(1399):     at android.widget.TextView.doKeyDown(TextView.java:5386)
05-20 17:17:23.943: E/AndroidRuntime(1399):     at android.widget.TextView.onKeyDown(TextView.java:5206)
05-20 17:17:23.943: E/AndroidRuntime(1399):     at android.view.KeyEvent.dispatch(KeyEvent.java:2533)
05-20 17:17:23.943: E/AndroidRuntime(1399):     at android.view.View.dispatchKeyEvent(View.java:5446)
05-20 17:17:23.943: E/AndroidRuntime(1399):     at android.view.ViewGroup.dispatchKeyEvent(ViewGroup.java:1248)
05-20 17:17:23.943: E/AndroidRuntime(1399):     at android.view.ViewGroup.dispatchKeyEvent(ViewGroup.java:1248)
05-20 17:17:23.943: E/AndroidRuntime(1399):     at android.view.ViewGroup.dispatchKeyEvent(ViewGroup.java:1248)
05-20 17:17:23.943: E/AndroidRuntime(1399):     at android.view.ViewGroup.dispatchKeyEvent(ViewGroup.java:1248)
05-20 17:17:23.943: E/AndroidRuntime(1399):     at com.android.internal.policy.impl.PhoneWindow$DecorView.superDispatchKeyEvent(PhoneWindow.java:1859)
05-20 17:17:23.943: E/AndroidRuntime(1399):     at com.android.internal.policy.impl.PhoneWindow.superDispatchKeyEvent(PhoneWindow.java:1361)
05-20 17:17:23.943: E/AndroidRuntime(1399):     at android.app.Activity.dispatchKeyEvent(Activity.java:2324)
05-20 17:17:23.943: E/AndroidRuntime(1399):     at com.android.internal.policy.impl.PhoneWindow$DecorView.dispatchKeyEvent(PhoneWindow.java:1806)
05-20 17:17:23.943: E/AndroidRuntime(1399):     at android.view.ViewRootImpl.deliverKeyEventPostIme(ViewRootImpl.java:3300)
05-20 17:17:23.943: E/AndroidRuntime(1399):     at android.view.ViewRootImpl.handleFinishedEvent(ViewRootImpl.java:3273)
05-20 17:17:23.943: E/AndroidRuntime(1399):     at android.view.ViewRootImpl.handleMessage(ViewRootImpl.java:2436)
05-20 17:17:23.943: E/AndroidRuntime(1399):     at android.os.Handler.dispatchMessage(Handler.java:99)
05-20 17:17:23.943: E/AndroidRuntime(1399):     at android.os.Looper.loop(Looper.java:137)
05-20 17:17:23.943: E/AndroidRuntime(1399):     at android.app.ActivityThread.main(ActivityThread.java:4340)
05-20 17:17:23.943: E/AndroidRuntime(1399):     at java.lang.reflect.Method.invokeNative(Native Method)
05

-20 17:17:23.943: E/AndroidRuntime(1399):   at java.lang.reflect.Method.invoke(Method.java:511)
05-20 17:17:23.943: E/AndroidRuntime(1399):     at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:784)
05-20 17:17:23.943: E/AndroidRuntime(1399):     at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:551)
05-20 17:17:23.943: E/AndroidRuntime(1399):     at dalvik.system.NativeStart.main(Native Method)

This is my mask class:

package suporte;

import android.text.Editable;
import android.text.TextWatcher;
import android.widget.EditText;

public abstract class Mask {

    public static String unmask(String s) {
    return s.replaceAll("[.]", "").replaceAll("[-]", "")
            .replaceAll("[/]", "").replaceAll("[(]", "")
            .replaceAll("[)]", "");
}

    public static TextWatcher insert(final String mask, final EditText ediTxt, final int length) {
        return new TextWatcher() {
            boolean isUpdating;
            String old = "";

            public void onTextChanged(CharSequence s, int start, int before,
                    int count) {
                String str = Mask.unmask(s.toString());
                String mascara = "";
                if (isUpdating) {
                    old = str;
                    isUpdating = false;
                    return;
                }
                int i = 0;
                for (char m : mask.toCharArray()) {
                    if (m != '#' && str.length() > old.length()) {
                        mascara += m;
                        continue;
                    }
                    try {
                        mascara += str.charAt(i);
                    } catch (Exception e) {
                        break;
                    }
                    i++;
                }
                isUpdating = true;
                ediTxt.setText(mascara);
                ediTxt.setSelection(mascara.length());
            }

            public void beforeTextChanged(CharSequence s, int start, int count,
                    int after) {
            }

            public void afterTextChanged(Editable s) {
            }
        };
    }

}

When I type 11.111.111 / 1111-11 and then + 1, it gives the error. The mask that I pass is: ##. ####. ### / #### - ##

Debugging, I discovered that the error occurs at some point that the android api will try to use the editText buffer, which I do not know because it gets the size 19 (which in this case is the size of the String inserted in EditText) should be 18, because before setSelection I made a new setText.

    
asked by anonymous 20.05.2014 / 19:26

1 answer

1

I think ideally you should actually use a limitation on the field itself and solve this problem.

Your field is specific and has a specific mask, so why leave it open for more characters than it actually needs? :)

An addition to this method of applying generic mask, which is very good, is that there is a problem there that is at the time of erasing the mask goes away, getting very ugly .. in phone cases, eg if you typed an extra number and remove and the final number is correct, it will run out of proper formatting! I solved this question by changing the code above for this:

int i = 0;
if(  str.length() > old.length()){
    for (char m : mask.toCharArray()) {
        if (m != '#') {
        mascara += m;
            continue;
        }else{
            try {
                mascara += str.charAt(i);
            } catch (Exception e) {
                break;
            }
            i++;
        }
    }
}else{
    mascara = s.toString();
}
    
22.05.2014 / 14:40