java 使用 TextWatcher 进行 EditText 验证
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/4248954/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
EditText validation with TextWatcher
提问by Tivie
I have a Dialog with a EditText
and a button. This EditText
will name the database table I will create so its of the utmost importance it is validated. So i would like to pose 2 questions:
我有一个 DialogEditText
和一个按钮。这EditText
将命名我将创建的数据库表,因此对其进行验证至关重要。所以我想提出两个问题:
1) This is quite simple, but i couldn't fin it anywhere: what characters can a database table name accept? Can it accept numbers? And can a number be the first character?
1)这很简单,但我在任何地方都找不到:数据库表名可以接受哪些字符?它可以接受数字吗?数字可以是第一个字符吗?
2) I've managed to validate the EditText
using TextWtacher
. Here's the code:
2)我已经设法验证EditText
使用TextWtacher
. 这是代码:
et_name.addTextChangedListener(new TextWatcher() {
public void afterTextChanged(Editable s) {
String filtered_str = s.toString();
if (filtered_str.matches(".*[^a-z^0-9].*")) {
filtered_str = filtered_str.replaceAll("[^a-z^0-9]", "");
s.clear();
// s.insert(0, filtered_str);
Toast.makeText(context,
"Only lowercase letters and numbers are allowed!",
Toast.LENGTH_SHORT).show();
}
}
public void beforeTextChanged(CharSequence s, int start, int count, int after) {}
public void onTextChanged(CharSequence s, int start, int before, int count) {}
});
Currently, if the user inserts any character other than lowercase letters and numbers, the textbox is cleared.
If I uncomment s.insert(0, filtered_str);
in order to to replace the EditText with the filtered string, my app hangs. And guess what I find in the debug?
目前,如果用户插入小写字母和数字以外的任何字符,则文本框将被清除。如果我取消注释s.insert(0, filtered_str);
以便用过滤后的字符串替换 EditText,我的应用程序会挂起。猜猜我在调试中发现了什么?
ERROR/AndroidRuntime(2454): java.lang.StackOverflowError
=D
错误/AndroidRuntime(2454):java.lang.StackOverflowError
=D
The question is... how can I replace the s text?
问题是...如何替换 s 文本?
-> s.replace(0, s.toString().length(), filtered_str);
(remove s.clear, of course) doesn't seem to work either.
-> s.replace(0, s.toString().length(), filtered_str);
(当然,删除 s.clear)似乎也不起作用。
采纳答案by Tivie
After some headbanging, I finally found the solution. Seems s.append(filtered_str) after s.clear() works. Dunno why it hasn't work before.
经过一番折腾,终于找到了解决办法。在 s.clear() 工作之后似乎 s.append(filtered_str) 。不知道为什么它以前不起作用。
回答by El David
private TextWatcher listenerTextChangedFiltro = new TextWatcher() {
public void afterTextChanged(Editable editable) {
final String textoFiltrado = StaticString.filterTextCustom(String.valueOf(editable.toString().toLowerCase()));
if (!textoFiltrado.equals(editable.toString().toLowerCase())) {
editable.clear();
editable.append(textoFiltrado);
}
}
};
回答by Sheshadri Mantha
hey! i'm trying similar thing with forcing the input text to be all lowercase; s.clear() followed by s.append() causes a StackOverflow for me too (or still).
嘿!我正在尝试类似的事情,强制输入文本全部为小写;s.clear() 后跟 s.append() 也会(或仍然)对我造成 StackOverflow。
wonder why Android puts us thru' hoops to force conversion to lowercase ?
想知道为什么 Android 会让我们陷入困境以强制转换为小写?
Since using TextWatcher was crashing for me (rightly so... and i couldn't figure out how to work spans), i looked at TransformationMethod.
由于使用 TextWatcher 对我来说崩溃了(这是正确的......而且我无法弄清楚如何工作跨度),我查看了 TransformationMethod。
1st try was to do an inline TransformationMethod on the EditText with something like this:
第一次尝试是在 EditText 上使用以下内容执行内联 TransformationMethod:
et.setTransformationMethod(new TransformationMethod() {
public void onFocusChanged(View view, CharSequence sourceText, boolean focused, int direction,
Rect previouslyFocusedRect) {
}
public CharSequence getTransformation(CharSequence source, View view) {
String ret = source.toString().toLowerCase();
System.out.println(ret);
return ret;
}
});
This caused crash due to IndexArrayOutOfBounds as soon as i typed a single char in the ET... could not figure out why.
一旦我在 ET 中输入一个字符,这就会由于 IndexArrayOutOfBounds 导致崩溃......无法弄清楚原因。
So, i checked the code for PasswordTransformation and then ReplacementTransformation -- both seem very complicated and i didn't want to bother with all that ?stuff?.
所以,我检查了 PasswordTransformation 和 ReplacementTransformation 的代码——两者看起来都很复杂,我不想打扰所有这些?东西?。
Then in checked out the SinglelineTransformation subclass which was simple... so i created LowerCaseTransformation as subclass of ReplacementTransformation as follows:
然后检查了简单的 SinglelineTransformation 子类……所以我创建了 LowerCaseTransformation 作为 ReplacementTransformation 的子类,如下所示:
public class LowerCaseReplacement extends ReplacementTransformationMethod {
private static final char[] ORIG = { 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O',
'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z' };
private static final char[] REPS = { 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o',
'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z' };
private static LowerCaseReplacement singleton;
@Override
protected char[] getOriginal() {
return ORIG;
}
@Override
protected char[] getReplacement() {
return REPS;
}
public static LowerCaseReplacement getInstance() {
if (singleton == null)
singleton = new LowerCaseReplacement();
return singleton;
}
}
}
and adding this xform to et... as in et.setTransformationMethod(LowerCaseReplacement.getInstnace())...
并将这个 xform 添加到 et... 就像 et.setTransformationMethod(LowerCaseReplacement.getInstnace())...
This works!!
这有效!!
If anyone has a better solution, then please enlighten!
如果有人有更好的解决方案,那么请赐教!
回答by kgiannakakis
The problem is that when you call the insert method, the text changed method is called again. This results in a vicious circle, thus the stack overflow. You can avoid this by not replacing a string that is properly formatted.
问题是当你调用insert方法时,又调用了text changed方法。这导致恶性循环,从而堆栈溢出。您可以通过不替换格式正确的字符串来避免这种情况。