我试图限制一个字符的编辑文本,我有一个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