TextWatcher,清除编辑文本的问题

时间:2017-08-29 17:36:26

标签: android filter android-edittext textwatcher

我试图限制一个字符的编辑文本,我有一个CustomTextWatcher类来处理所有文本更改事件。让我们说如果我写一个字母,焦点将自动跳转到下一个编辑文本,但如果我触摸editText到getFocus如果光标在前一个字母之前它允许我写一个字母为2然后,我尝试清除编辑文本在beforeTextChanged但它崩溃了应用程序,任何关于如何解决这个问题的想法?

@Override
public void beforeTextChanged(CharSequence s, int start, int count, int after) {
    EditText e = (EditText) v;
    if(e.getText().toString().length() == 0 || e.getText().toString().equals(""))
        e.setText(s); // if true means there is no previous text so i can just use whatever comes in s charSequence
    else
        e.setText(""); // if false, means there is some text, so i want to clean it up first and write new character
    Log.d(TAG, "beforeTextChanged: ");
}

更新:好的,所以在遵循推荐之后,这就是我所拥有的:

@Override
public void beforeTextChanged(CharSequence s, int start, int count, int after) {
    hasToClear = false;
    e = (EditText) v;
    if(e.getText().toString().length() > 0 || !e.getText().toString().equals("")) {
        previousChar = e.getText().toString(); // if either true, the box was not empty
        hasToClear = true;
    }
    Log.d(TAG, "beforeTextChanged: ");
}


@Override
public void afterTextChanged(Editable s) {

    InputFilter[] editFilters = s.getFilters();
    InputFilter[] newFilters = new InputFilter[editFilters.length + 2];
    System.arraycopy(editFilters, 0, newFilters, 0, editFilters.length);
    newFilters[editFilters.length] = new InputFilter.AllCaps();
    if(!isNumber)
        newFilters[editFilters.length+1] = charFilter;
    else
        newFilters[editFilters.length + 1] = digitFilter;
    s.setFilters(newFilters);
    if(isAllowed) {
        if (i == NUM_DIGITS) {
            edList[5].clearFocus();
            onTextFinishedListener.onPlateFinished(true);
        } else {
            edList[i].selectAll();
            edList[i].requestFocus();
        }
    }
    String stringToReplace = "";
    if(previousChar != null) { // find which caracter is diferent as there is only one allowed
        for (int x = 0; x < s.length(); x++) {
            if (s.charAt(x) != previousChar.charAt(0)) {
                stringToReplace = String.valueOf(s.charAt(x));
                break;
            } else stringToReplace = String.valueOf(previousChar);
        }
    }
    if(hasToClear){ // if true clear
        e.removeTextChangedListener(this);
        e.setText("");
        e.setText(stringToReplace);
        e.addTextChangedListener(this);
    }
}

如果用户点击,在下一个输入用户所做的任何字符之前或之后,必须替换为前一个字符,这会发生在之前和之后的字符上,但不会发生在

之后

3 个答案:

答案 0 :(得分:1)

来自beforeTextChanged的{​​{3}}:

  

调用此方法是为了在s内通知您计数   从开始开始的字符即将被新文本替换   之后的长度。 尝试对s进行更改是错误的   这个回调。

因此,您应将相同的代码移至afterTextChanged,以便对EditText进行更改是合法的。

注意:如果您在同一afterTextChanged的{​​{1}} 中设置文字,则 EditText将被解除。如果这不是预期的行为,应删除TextWatcher 设置文字,然后添加TextWatcher

答案 1 :(得分:0)

为什么使用该代码,您可以使用它。

@Override
public void beforeTextChanged(CharSequence s, int start, int count, int after) {
    EditText e = (EditText) v;
    if(e == null)
        e.setText(s); 
    else
        e.setText(null); 
    Log.d(TAG, "beforeTextChanged: ");
}

此外,您可以将onClickListener设置为edittext。如果edittext不为空并且再次点击,则会e.setOnClickListener(new View.OnClickListener() { @Override public void onClick(final View arg0) { if(e != null){ e.setText(null); } else {} } }); 为空。

beforeTextChanged

您也可以在else的空白onClick内拨打if(isset($_REQUEST['username'])) { $username = $_REQUEST['username']; } else { die('User is blank'); //$username = ""; } 方法。

答案 2 :(得分:0)

在处理不同的方法后,我决定放弃输入过滤器,假设它们没有按照我希望的方式运行,所以为了不通过阻止xml中的字符来打破UI,我使用两种方法:

private boolean validateLetter(Character s){
    if(s == null)
        return false;
    if(!Character.isLetter(s)) { //if it isn't a letter, throw message
        Toast.makeText(mContext, "Character not allowed", Toast.LENGTH_SHORT).show();
        return false;
    } else {
        return true;
    }
}

private boolean validateNumber(Character s){
    if(s == null)
        return false;
    if(!Character.isDigit(s)) { // if it isn't a digit, throw message-
        Toast.makeText(mContext, "Character not allowed", Toast.LENGTH_SHORT).show();
        return false;
    } else {
        return true;
    }
}

,TextWatcher如下所示:

@Override
public void beforeTextChanged(CharSequence s, int start, int count, int after) {
    hasToClear = false;
    isAllowed = false;
    e = (EditText) v;
    if(e.getText().toString().length() > 0 || !e.getText().toString().equals("")) {
        previousChar = e.getText().toString(); //store previous char if there is any
        hasToClear = true; // rise flag for clearing field in after event
    }
    Log.d(TAG, "beforeTextChanged: ");
}

@Override
public void onTextChanged(CharSequence s, int start, int before, int count) {
    isNumber = false;
    String[] data= v.getTag().toString().split(";"); //recieve the type of input for the edit text and its position in the layout by xml tag
    String type = data[0];
    pos = Integer.parseInt(data[1]);
    if(type.equals("number"))
        isNumber = true;
}

@Override
public void afterTextChanged(Editable s) {

    Character stringToReplace = null;
    if(previousChar != null) { // 
        for (int x = 0; x < s.length(); x++) {
            if (s.charAt(x) != previousChar.charAt(0)) { //this bucle find the different character in the edit text
                stringToReplace = s.charAt(x);
                break;
            } else stringToReplace = previousChar.charAt(0);
        }
    }
    if(isNumber){
        if(validateNumber(stringToReplace)){
            isAllowed = true;
        }else isAllowed = false;
    }else
        if(validateLetter(stringToReplace)){
            isAllowed = true;
        } else isAllowed = false;

    if(isAllowed) {
        if(hasToClear){
            e.removeTextChangedListener(this); //remove listener
            e.setText(""); //clear field
            e.setText(String.valueOf(stringToReplace)); //add new value
            e.addTextChangedListener(this); //add listener back
        }
        if (pos == NUM_DIGITS) { //jump to next editText until it reaches NUM_DIGITS, after will notify that it has finished filling all editText
            edList[5].clearFocus();
            onTextFinishedListener.onPlateFinished(true);
        } else {
            edList[pos].selectAll();
            edList[pos].requestFocus();
        }
    } else {
        if(previousChar != null) {
            e.removeTextChangedListener(this);
            e.setText(String.valueOf(previousChar));
            e.addTextChangedListener(this);
        }
    }
    isAllowed = false;
}

特别感谢

  

@Veneet Reddy