【问题标题】:IndexOutOfBoundsException setSpan (0 ... 1) ends beyond length 0IndexOutOfBoundsException setSpan (0 ... 1) 结束于长度 0
【发布时间】:2015-12-28 19:57:20
【问题描述】:

我正在将此库用于带有标签的材料editText: https://github.com/rey5137/Material/wiki/Text-Field 不错的图书馆:)

但是……

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

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) 

任何想法为什么会发生?以及如何解决这个问题??

【问题讨论】:

    标签: android android-edittext indexoutofboundsexception textwatcher


    【解决方案1】:

    在这段代码sn-p中,你缩短了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().clear();字符串混乱 = getString(R.string.toast_login_useLatin); showToastMessage(mess);
    • 堆栈跟踪显示异常发生在系统处理消息时。崩溃发生时,您的代码根本不在堆栈中。
    • 您需要确定s 中的哪些字符“不正确”,删除它们,然后确定您要选择的字符(如果有)。
    • hm,看起来和我做的一样...第一个符号是错误的,所以我尝试清除 mEdit.pass ....
    • 请看我编辑的答案。看起来您的 Toast 消息要求用户修复字符串,因此我建议的代码将选择设置为第一个错误符号。文本根本没有改变。
    【解决方案2】:

    通过添加下一个代码解决了这个问题:

    mEditPass.getText().clearSpans();
    

    之前

    mEditPass.getText().clear();
    

    【讨论】:

      【解决方案3】:

      错误表示您在开始之前结束可跨文本,查找您给结束的任何字符以及它在开始之前出现的字符

      【讨论】:

        【解决方案4】:

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

        mEditPass.setSelection(new string);
        

        【讨论】:

          【解决方案5】:

          你应该修剪文本。

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

          【讨论】:

            猜你喜欢
            • 2012-01-25
            • 1970-01-01
            • 2018-07-12
            • 2020-05-31
            • 1970-01-01
            • 2017-12-22
            • 2019-01-25
            • 2018-07-02
            • 1970-01-01
            相关资源
            最近更新 更多