Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/android/216.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Android IndexOutOfBoundsException设置范围(0…1)结束时长度超过0_Android_Android Edittext_Indexoutofboundsexception_Textwatcher - Fatal编程技术网

Android IndexOutOfBoundsException设置范围(0…1)结束时长度超过0

Android IndexOutOfBoundsException设置范围(0…1)结束时长度超过0,android,android-edittext,indexoutofboundsexception,textwatcher,Android,Android Edittext,Indexoutofboundsexception,Textwatcher,我将此库用于带标签的材质editText: 尼斯图书馆:) 但是 我正在使用下一个代码检查输入的符号是否正确: private boolean hasCorrectSymbols(String input){ String tre = "[A-Za-z0-9\\@\\#\\$\\%\\&\\*\\(\\)\\-\\+\\_\\;\\:\\?\\.\\,\\!]+$"; if (input.matches(tre)){ return

我将此库用于带标签的材质editText: 尼斯图书馆:)

但是

我正在使用下一个代码检查输入的符号是否正确:

private boolean hasCorrectSymbols(String input){
        String tre = "[A-Za-z0-9\\@\\#\\$\\%\\&\\*\\(\\)\\-\\+\\_\\;\\:\\?\\.\\,\\!]+$";
        if (input.matches(tre)){
            return true;
        }
        return false;
    }
为了检查正确的符号,我正在使用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) {}
        });
如果第一个符号正确,第二个符号错误-系统将剪切最后输入的(错误)符号并将光标设置到最后一个文本位置,但如果第一个符号是禁止符号-系统将因此错误崩溃:

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) 

你知道为什么会这样吗?如何解决这个问题?

在这个代码片段中,您可以缩短
EditText
中显示的文本(以便最后一个有效位置是
start-1
),但仍然尝试将选择位置设置为
start

                text = text.substring(0, start);
                mEditPass.setText(text);
                mEditPass.setSelection(start);
[已编辑]

假设您的Toast消息提示用户修复错误,我认为您实际上要做的是将选择设置为EditText中带有错误符号的第一个字符。下面是执行此操作的示例代码:

// 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) {
        }
    });

通过添加下一个代码修复了此问题:

mEditPass.getText().clearSpans();
以前

mEditPass.getText().clear();

错误表示您要在可扩展文本开始之前结束该文本,请查找您指定要结束的任何字符及其在开始之前出现的字符

只需在字符串中再添加一个空格,然后

mEditPass.setSelection(new string);

你应该修剪一下文本

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

不,它在第一个符号错误时崩溃,在这里崩溃:mEditPass.getText().clear();stringmess=getString(R.String.toast\u login\u useLatin);showToastMessage(混乱);堆栈跟踪显示系统在处理消息时发生异常。崩溃发生时,您的代码根本不在堆栈上。您需要确定
s
中的哪些字符“不正确”,将其删除,然后确定要选择的字符(如果有)。嗯,看起来与我尝试执行的相同。。。第一个符号错误,所以我尝试清除mEdit.pass…请查看我编辑的答案。看起来您的Toast消息要求用户修复字符串,因此我建议的代码将选择设置为第一个坏符号。文本一点也没有改变。