10

I am using this library for material editText with label: https://github.com/rey5137/Material/wiki/Text-Field nice library :)

but...

i am using next code to check are entered symbols correct:

private boolean hasCorrectSymbols(String input){
        String tre = "[A-Za-z0-9\\@\\#\\$\\%\\&\\*\\(\\)\\-\\+\\_\\;\\:\\?\\.\\,\\!]+$";
        if (input.matches(tre)){
            return true;
        }
        return false;
    }

for checking correct symbols I am using textWatcher:

mEditPass.addTextChangedListener(new TextWatcher() {
            @Override
            public void beforeTextChanged(CharSequence s, int start, int count, int after) {}

            @Override
            public void onTextChanged(CharSequence s, int start, int before, int count) {
                if (s.length() == 1 && !loginPassHasCorrectSymbols(s.toString())){
                    mEditPass.getText().clear();
                    String mess = getString(R.string.toast_login_useLatin);
                    showToastMessage(mess);
                } else if (s.length() >1 && !loginPassHasCorrectSymbols(s.toString())) {
                    String mess = getString(R.string.toast_login_useLatin);
                    showToastMessage(mess);
                    String text = s.toString();
                    text = text.substring(0, start);
                    mEditPass.setText(text);
                    mEditPass.setSelection(start);
                }
            }

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

if first symbol is correct and the second one for example is wrong - system will cut last entered (wrong) symbol and set cursor to the last text position, but if the first symbol is prohibited symbol - it will crash with this error:

java.lang.IndexOutOfBoundsException: setSpan (0 ... 1) ends beyond length 0
            at android.text.SpannableStringBuilder.checkRange(SpannableStringBuilder.java:1016)
            at android.text.SpannableStringBuilder.setSpan(SpannableStringBuilder.java:592)
            at android.text.SpannableStringBuilder.setSpan(SpannableStringBuilder.java:588)
            at android.text.method.PasswordTransformationMethod.onTextChanged(PasswordTransformationMethod.java:108)
            at android.text.SpannableStringBuilder.sendTextChanged(SpannableStringBuilder.java:962)
            at android.text.SpannableStringBuilder.replace(SpannableStringBuilder.java:496)
            at android.text.SpannableStringBuilder.replace(SpannableStringBuilder.java:435)
            at android.text.SpannableStringBuilder.replace(SpannableStringBuilder.java:30)
            at android.view.inputmethod.BaseInputConnection.replaceText(BaseInputConnection.java:683)
            at android.view.inputmethod.BaseInputConnection.commitText(BaseInputConnection.java:198)
            at com.android.internal.widget.EditableInputConnection.commitText(EditableInputConnection.java:183)
            at com.android.internal.view.IInputConnectionWrapper.executeMessage(IInputConnectionWrapper.java:279)
            at com.android.internal.view.IInputConnectionWrapper$MyHandler.handleMessage(IInputConnectionWrapper.java:77)
            at android.os.Handler.dispatchMessage(Handler.java:102)
            at android.os.Looper.loop(Looper.java:136)
            at android.app.ActivityThread.main(ActivityThread.java:5097)
            at java.lang.reflect.Method.invokeNative(Native Method)
            at java.lang.reflect.Method.invoke(Method.java:515)
            at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:785)
            at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:601)
            at dalvik.system.NativeStart.main(Native Method) 

Any ideas why it happen? And how to fix this??

Stan Malcolm
  • 2,740
  • 5
  • 32
  • 53

5 Answers5

6

In this code snippet, you shorten the text displayed in the EditText (so that the last valid position is start-1), but still try to set the selection position to start.

text = text.substring(0, start);
mEditPass.setText(text);
mEditPass.setSelection(start);

[EDITED]

Assuming that your Toast message is prompting the user to fix the error, I think what you actually want to do is to set the selection to the first character in the EditText with a bad symbol. Here is sample code for doing that:

// A reusable Pattern (at the class level) that defines the regex for bad characters.
private static final Pattern ILLEGAL_CHAR_PATTERN = Pattern.compile(
    "[^A-Za-z0-9\\@\\#\\$\\%\\&\\*\\(\\)\\-\\+\\_\\;\\:\\?\\.\\,\\!]"
);

    // Replacement for your listener code.
    mEditPass.addTextChangedListener(new TextWatcher() {
        @Override
        public void beforeTextChanged(CharSequence s, int start, int count, int after) {
        }

        @Override
        public void onTextChanged(CharSequence s, int start, int before, int count) {
            if (s.length() == 0 || count == 0) {
                return;
            }
            Matcher matcher = ILLEGAL_CHAR_PATTERN.matcher(s);
            if (matcher.find()) {
                int firstIllegalPos = matcher.start();
                mEditPass.setSelection(firstIllegalPos);
                String mess = getString(R.string.toast_login_useLatin);
                showToastMessage(mess);
            }
        }

        @Override
        public void afterTextChanged(Editable s) {
        }
    });
this
  • 94
  • 1
  • 6
cybersam
  • 63,203
  • 6
  • 53
  • 76
  • nope, it crashed when the first symbol is wrong, and it crash here: mEditPass.getText().clear(); String mess = getString(R.string.toast_login_useLatin); showToastMessage(mess); – Stan Malcolm Sep 30 '15 at 22:24
  • The stack trace shows that the exception happened when the system was handling a message. Your code was not on the stack at all when the crash happened. – cybersam Sep 30 '15 at 22:30
  • You need to determine which characters in `s` are "incorrect", remove them, and then determine what character you want to select (if any). – cybersam Sep 30 '15 at 22:49
  • hm, it looks the same I am trying to do... the first symbol is wrong, so i try to clear mEdit.pass.... – Stan Malcolm Sep 30 '15 at 22:59
  • Please see my edited answer. It looks like your Toast message is asking the user to fix the string, so my proposed code sets the selection to the first bad symbol. The text is not changed at all. – cybersam Oct 01 '15 at 00:14
2

This problem was fixed by adding next code:

mEditPass.getText().clearSpans();

before

mEditPass.getText().clear();
Stan Malcolm
  • 2,740
  • 5
  • 32
  • 53
1

The Error says you are ending the spanable text before its start, look for any character that you gave to end and its appearing before start

blackHawk
  • 6,047
  • 13
  • 57
  • 100
1

you should trim the text.

spannable.setSpan(
            ForegroundColorSpan(textColor),
            FIRST_INDEX, someText.trim().length,
            Spannable.SPAN_EXCLUSIVE_EXCLUSIVE)
0

just add one more space to your string and then

mEditPass.setSelection(new string);
Buddy
  • 10,874
  • 5
  • 41
  • 58
Vikash Sharma
  • 539
  • 8
  • 13