我需要将可以输入到TextInputEditText
中的输入限制为两个大写字母和一两个数字,如AB01、CS8、XY99或ND5。
所以我写了这个方法
/**
* @return an InputFilter that restricts input to the format of two capital letters and one or two digits
*/
public static InputFilter getClientIdInputFilter() {
return (source, start, end, dest, dstart, dend) -> {
Log.v(DEBUG_TAG, "----\nsource: " + source + ", start: " + start + ", end: " + end + ", dest: " + dest + ", dstart: " + dstart + ", dend: " + dend);
String destTxt = dest.toString();
String input = destTxt.substring(0, dstart) + source.subSequence(start, end) + destTxt.substring(dend);
Log.v(DEBUG_TAG, input);
if (input.matches("^[A-Z]{0,2}[0-9]{0,2}$")) {
if (input.length() == 1 && input.matches("^[0-9]$")) {
Log.v(DEBUG_TAG, "Invalid input A");
return "";
}
if (input.length() == 2 && !input.matches("^[A-Z]{2}$")) {
Log.v(DEBUG_TAG, "Invalid input B");
return "";
}
Log.v(DEBUG_TAG, "Valid input");
return null;
}
Log.v(DEBUG_TAG, "Invalid input C");
return "";
};
}
我是这样用的:
TextInputEditText clientId = dialogView.findViewById(R.id.edit_text_client_id);
InputFilter[] clientIdFilters = new InputFilter[1];
clientIdFilters[0] = InputFilterUtils.getClientIdInputFilter();
clientId.setFilters(clientIdFilters);
它 * 几乎 * 工作完美...
问题是only当从空的textfield
开始输入时,在前两个大写字母之后(所以在第三个字母处),该字段被完全删除。相反,如果先输入数字(并且被正确地忽略),如果继续输入字母,当到达第三个字母时,这一次前两个字母保留,用户可以继续输入数字...
我对这种行为没有任何线索(我添加了一些日志条目,但无论如何都不清楚)
4条答案
按热度按时间cvxl0en21#
为什么要用regex来做这个呢?这是一个简单的验证逻辑。
57hvy0tb2#
如果你想使用regex方法使用下面。
fcipmucu3#
我可以理解@xenon134的答案,它实际上并不检查第一个和第二个字符是否是字母,所以,由于输入应该限制在3或4个字符,我会使用一个更硬编码的解决方案,而不是过度设计,所以:
input.charAt(index)
public static boolean isLetter(char c) { ... }
public static boolean isNumber(char c) { ... }
bsxbgnwa4#
实际上问题不在代码中;它在Google Pixel 3上的表现和预期完全一样可能所有的谷歌设备都会有同样的结果。
但是,当在三星设备上尝试时,这个空的
TextInputEditText
行为开始出现。This answer证明了三星设备的另一个问题。
因此,
InputFilter
的行为因设备/制造商而异,这可能与软输入键盘有关,而不是制造商。无论如何,这需要以不同于
InputFilter
所期望的方式来处理;下面是我们发现的处理方法:source
变量只返回最后一个输入字符。source
变量返回整个字符串。return ""
将最后一个输入字符替换为""
(如预期)。return ""
将整个输入字符串替换为""
(这就是TextInputEditText
重置为空字符串的原因)。有了这些观察结果,我们可以通过检查
source
的长度来修复这个问题。如果它是1,那么这是正常的行为,所以返回""
;否则,我们需要返回String的匹配部分,而不是""
。一个奇怪的情况发生时,开始了一个数字,这将是正常的封锁;但是当你之后打一封信的时候则发送该数字而不是该字母。2这可以通过在返回字符串之前删除前导数字来处理。
进行这些更改后,以下是修改后的版本: