6

我有一个带有 TextWatcher 的 EditText。它应该将文本格式化为 5'9" 这样的人类高度。但是当用户犯错并想要删除错误输入的字符时,TextWather 不允许他这样做。假设用户想要删除“字符” TextWath 立即添加它。下面是代码。那么如何允许用户删除 EditText 中的文本呢?

private class CustomTextWatcher implements TextWatcher {
    private EditText mEditText;

public CustomTextWatcher(EditText e) {
    mEditText = e;
}

public void beforeTextChanged(CharSequence s, int start, int count,
        int after) {
}

public void onTextChanged(CharSequence s, int start, int before,
        int count) {


}

public void afterTextChanged(Editable s) {
    int count = s.length();
    String str = s.toString();
    if (count == 1) {
        str = str + "'";
    } else if (count == 3) {
        str = str + "\"";
    } else if ((count > 4) && (str.charAt(str.length() - 1) != '\"')) {
        str = str.substring(0, str.length() - 2)
                + str.charAt(str.length() - 1) + "\"";
    } else {
        return;
    }
    mEditText.setText(str);
    mEditText.setSelection(mEditText.getText().length());


}

}

4

2 回答 2

8

忽略 Karakuri 发布的关于您的代码在错误回调中的事实,您可以添加一个简单的修复程序,您只需聆听用户使用的键。

如果没有对现有代码进行任何实际测试或进一步改进,这似乎可以解决您描述的问题:

package com.example.testwatchertest;

import android.app.Activity;
import android.os.Bundle;
import android.text.Editable;
import android.text.TextWatcher;
import android.view.KeyEvent;
import android.view.View;
import android.view.View.OnKeyListener;
import android.widget.EditText;

public class MainActivity extends Activity implements TextWatcher {

    EditText editText;
    boolean keyDel = false;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        editText = (EditText) findViewById(R.id.editText);
        editText.addTextChangedListener(this);

        editText.setOnKeyListener(new OnKeyListener() {

            @Override
            public boolean onKey(View v, int keyCode, KeyEvent event) {

                if (keyCode == KeyEvent.KEYCODE_DEL){
                    keyDel = true;
                }else{
                    keyDel = false;
                }
                return false;
            }
        });

    }

    @Override
    public void afterTextChanged(Editable s) {
        // TODO Auto-generated method stub

    }

    @Override
    public void beforeTextChanged(CharSequence s, int start, int count, int after) {
        // TODO Auto-generated method stub

    }

    @Override
    public void onTextChanged(CharSequence s, int start, int before, int count) {

        if (!keyDel) {

            String str = s.toString();
            if (count == 1) {
                str = str + "'";
            } else if (count == 3) {
                str = str + "\"";
            } else if ((count > 4) && (str.charAt(str.length() - 1) != '\"')) {
                str = str.substring(0, str.length() - 2) + str.charAt(str.length() - 1) + "\"";
            } else {
                return;
            }
            editText.setText(str);
            editText.setSelection(editText.getText().length());

        }

    }

}
于 2012-12-28T16:17:12.350 回答
2

从文档

public abstract void onTextChanged (CharSequence s, int start, int before, int count)

调用此方法是为了通知您,在 s 内,从 start 开始的 count 个字符刚刚替换了之前有 length 的旧文本。尝试通过此回调对 s 进行更改是错误的。

您应该在 afterTextChanged() 中进行任何更改,而不是在其他两个回调中的任何一个中。

public abstract void afterTextChanged (Editable s)

调用此方法是为了通知您,在 s 中的某处,文本已更改。从这个回调中对 s 进行进一步的更改是合法的,但请注意不要让自己陷入无限循环,因为您所做的任何更改都会导致再次递归调用此方法。(您不会被告知更改发生的位置,因为其他afterTextChanged()方法可能已经进行了其他更改并使偏移量无效。但是如果您需要在这里知道,您可以使用 setSpan(Object, int, int, int)inonTextChanged(CharSequence, int, int, int)标记您的位置,然后从此处查找跨度结束的位置向上。)

于 2012-12-28T16:11:49.573 回答