我该如何解决这个Android TextWatcher限制?

时间:2014-08-18 09:56:31

标签: android textview

我在TextWatcher字段上定义了EditText。在TextWatcher.onTextChanged()方法中,我有时会将EditText值重置为空字符串。我什么时候得到

java.lang.IndexOutOfBoundsException: setSpan (2 ... 3) ends beyond length 0
    at android.text.SpannableStringBuilder.checkRange(SpannableStringBuilder.java:934)

任何人都可以建议一种解决方法,从TextWatcher中安全地清除EditText。

我的代码是......

TextWatcher tw = new TextWatcher() {
    public void onTextChanged (CharSequence chars, int start, int before,int count) {
        // if user keys Enter, process the contents and clear down the EditText
        if (chars.toString().indexOf("\n") > -1) {
            processChars(s.toString().replace("\n", ""));
            editTextField.setText("");
        }
    } 
};

editTextField.addTextChangedListener(tw);

2 个答案:

答案 0 :(得分:1)

正如@pskink在评论中提到的那样,“ 尝试从this回调 ”更改s是错误的。因此,请使用EditText,而不是直接更改Handler值。下面提供了一个示例供参考。

private EditText mEditText;
private TextWatcher mTextWatcher;

private static final int MSG_ADD_TEXTWATCHER = 100;
private static final int MSG_PROCESS_CHARS = 200;
private static final int MSG_REMOVE_TEXTWATCHER = 300;

private final MyHandler mHandler = new MyHandler(this);
private static class MyHandler extends Handler {
    private final WeakReference<MainActivity> myActivity;

    public MyHandler(MainActivity activity) {
        myActivity = new WeakReference<MainActivity>(activity);
    }

    @Override
    public void handleMessage(Message msg) {
        MainActivity activity = myActivity.get();
        if (activity != null) {
            switch (msg.what) {
                case MSG_ADD_TEXTWATCHER:
                    activity.addTextWatcher();
                    break;
                case MSG_PROCESS_CHARS:
                    activity.processChars(msg.obj.toString());
                    break;
                case MSG_REMOVE_TEXTWATCHER:
                    activity.removeTextWatcher();
                    break;
                default:
                    super.handleMessage(msg);
            }
        }
    }
}

...

@Override
public void onTextChanged(CharSequence s, int start, int before, int count) {
    if (s.toString().indexOf("\n") > -1) {
        Message msg = new Message();
        msg.what = MSG_PROCESS_CHARS;
        msg.obj = s.toString().replace("\n", "");
        mHandler.sendMessage(msg);
    }
}

...

private void addTextWatcher() {
    mEditText.addTextChangedListener(mTextWatcher);
}

private void removeTextWatcher() {
    mEditText.removeTextChangedListener(mTextWatcher);
    mEditText.setText("");
}

private void processChars(String msg) {
    Toast.makeText(this, msg, Toast.LENGTH_SHORT).show();
    mHandler.sendEmptyMessage(MSG_REMOVE_TEXTWATCHER);
}

您需要根据您的项目要求在适当的时候/ {适用于mHandler.sendEmptyMessage(MSG_ADD_TEXTWATCHER);

答案 1 :(得分:0)

致@Michael Shrestha,@ pskink和@shoe老鼠照亮道路。我接受的解决方案是迈克尔建议将代码从onTextChanged()移到afterTextChanged()