我试图限制一个字符的编辑文本,我有一个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);
}
}
如果用户点击,在下一个输入用户所做的任何字符之前或之后,必须替换为前一个字符,这会发生在之前和之后的字符上,但不会发生在
之后答案 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