其他分享
首页 > 其他分享> > 重写getText的EditText

重写getText的EditText

作者:互联网

我想覆盖EditText的getText().

我收到这样的字符串:“ 12,345,678”

我的目的是仅删除逗号并返回Editable,但是使用我的代码时出现错误.

public class AmountEditText extends EditText {
    @Override
    public Editable getText() {
        Editable s = super.getText();
        if(s!=null && s.length()>0) {
            if (s.toString().contains(",")) {
                return new SpannableStringBuilder(s.toString().replace(",", ""));
            }
        }
        return s;
    }
    private TextWatcher watcher = 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) {
            int position = getSelectionStart();
            int nbCommaBefore;
            int nbCommaAfter;
            String str = s.toString();
            String finalStr;
            String formattedStr;
            nbCommaBefore  = str.length() - str.replace(",", "").length();
            boolean containsDot = false;
            if (str.contains(".")) {
                containsDot = true;
                formattedStr = str.split("\\.")[0];

            } else {
                formattedStr = str;
            }
            if (!s.toString().isEmpty()) {
                removeTextChangedListener(watcher);
                formattedStr = formattedStr.replace(",", "");
                formattedStr = formattedStr.replaceAll("(\\d)(?=(\\d{3})+$)", "$1,");
                if (containsDot) {
                    if (str.split("\\.").length != 1) {
                        finalStr = formattedStr + "." + str.split("\\.")[1].replace(",", "");
                    } else {
                        finalStr = formattedStr + ".";
                    }
                } else {
                    finalStr = formattedStr;
                }
                nbCommaAfter  = finalStr.length() - finalStr.replace(",", "").length();
                setText(finalStr);
                if (position == str.length()){
                    setSelection(finalStr.length());
                }
                else if (position == 0)
                {
                    setSelection(0);
                }
                else if (nbCommaBefore < nbCommaAfter){
                    setSelection(position + 1);
                }

                else if (nbCommaAfter < nbCommaBefore){
                    setSelection(position - 1);
                }
                else{
                    setSelection(position);
                }
                addTextChangedListener(watcher);
            }
        }

        @Override
        public void afterTextChanged(Editable s) {
        }

    };

    public AmountEditText(Context context) {
        this(context, null);
    }

    public AmountEditText(Context context, AttributeSet attrs) {
        super(context, attrs);
        addTextChangedListener(watcher);
    }

    public AmountEditText(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        addTextChangedListener(watcher);
    }
}

E/MessageQueue-JNI: Exception in MessageQueue callback:
handleReceiveCallback E/MessageQueue-JNI:
java.lang.IndexOutOfBoundsException: setSpan (0 … 5) ends beyond
length 4
at android.text.SpannableStringBuilder.checkRange(SpannableStringBuilder.java:1265)
at android.text.SpannableStringBuilder.setSpan(SpannableStringBuilder.java:684)
at android.text.SpannableStringBuilder.setSpan(SpannableStringBuilder.java:677)
at android.widget.SpellChecker$SpellParser.setRangeSpan(SpellChecker.java:532)
at android.widget.SpellChecker$SpellParser.parse(SpellChecker.java:515)
at android.widget.SpellChecker.spellCheck(SpellChecker.java:242)
at android.widget.Editor.updateSpellCheckSpans(Editor.java:679)
at android.widget.Editor.sendOnTextChanged(Editor.java:1249)
at android.widget.TextView.sendOnTextChanged(TextView.java:8191)
at android.widget.TextView.setText(TextView.java:4483)
at android.widget.TextView.setText(TextView.java:4337)
at android.widget.EditText.setText(EditText.java:89)
at android.widget.TextView.setText(TextView.java:4312)
at org.newtonproject.newpay.widgetlib.AmountEditText$1.onTextChanged(AmountEditText.java:74)

我想精确地指出错误不是来自于onTextChanged
因为在没有覆盖getText()的情况下一切正常

编辑:用户可以输入数字,我将添加一些逗号以格式化数字.但是当我重写getText()时,我想以这种方式删除这些逗号,而不必每次都过滤getText()的返回值.

解决方法:

在您的情况下,您不能覆盖getText()并同时调整大小和使用TextWatcher.

检查下面的Android源代码,您将为什么

SpannableStringBuilder.java

public void setSpan(Object what, int start, int end, int flags) {
    setSpan(true, what, start, end, flags, true/*enforceParagraph*/);
}

private void setSpan(boolean send, Object what, int start, int end, int flags,
            boolean enforceParagraph) {
    checkRange("setSpan", start, end);
}

private void checkRange(final String operation, int start, int end) {
    ...
    int len = length();
    if (start > len || end > len) {
        throw new IndexOutOfBoundsException(operation + " " +
                    region(start, end) + " ends beyond length " + len); // here is you exception
    }
}

public int length() {
    return mText.length - mGapLength;
}

SpellChecker.java

private void setRangeSpan(Editable editable, int start, int end) {
    ...
    editable.setSpan(mRange, start, end, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
}

public void parse(int start, int end) {
    ...
    if (parseEnd > start) {
        setRangeSpan((Editable) mTextView.getText(), start, parseEnd); // I think the error happened from here, they use your getText() function here and receive shorter string, but the start, parseEnd still stick with original string
        parse();
    }
}

解决方法.
您可以简单地定义一个新函数,例如getBeautifulText().

标签:android-edittext,spannablestring,android
来源: https://codeday.me/bug/20191108/2005906.html