文本观看者,清除编辑文本的问题



我试图限制一个字符的编辑文本,我有一个CustomTextWatcher类,该类处理所有文本更改事件。可以说,如果我写一封信,焦点将自动跳到下一个编辑文本,但是如果我触摸了deDittext以获取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);
    }
}

如果用户单击任何字符之前或之后,下一个输入用户必须替换为先前的字符,则在

之后不会发生这种情况,但不会发生这种情况。

来自 beforeTextChanged的文档:

此方法被调用是为了通知您,在s中,计数 从开始时开始的角色将被新文本替换 长度之后。尝试从 此回调。

因此,您应该将相同的代码移至afterTextChanged,其中更改EditText是合法的。

注意:如果在同一 EditText上设置了 afterTextChanged 中的文本,则将 TextWatcher被触发。如果这不是打算的行为,则应删除TextWatcher 设置文本,然后添加TextWatcher back。

为什么要使用该代码,可以使用此代码。

@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 NULL。

e.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(final View arg0) {
               if(e != null){
                 e.setText(null);
                }
              else
               {}
            }
        });

您也可以在onClick的空白else中调用beforeTextChanged方法。

处理不同的方法后,我决定离开输入过滤器,可以说他们没有以我希望的方式行事仅阻止XML字符,我使用两种方法:

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

最新更新