最近由于公司需要,改做一个android的APP, 其中有一个功能,需要弹出一个对话框,要求用户输入IP地址。IPV4的地址。
IPV4的地址大家都知道是怎么一回事了。 按照产品的设计,应该是让用户分别输入四个地址段的数字,而不是一串字符串,这样可能客户体验好一些吧。
于是就有一个问题了,需要限制,每一个地址段的值,从0~255, 不允许其他内容。
首先,纯数字这个问题好解决,没有什么可说的。 但是数字不小于0,不大于255,这个似乎在Android上面没有什么现成的办法。由于android开发并非主业,所以大致搜索了一下,看看网上别人的解决方案,结果却是,网上大多数都是InputFilter来解决的,而且基本上都是用一下的代码来进行判断的:
@Override
public CharSequence filter(CharSequence source, int start, int end, Spanned dest, int dstart, int dend) {
try {
int input = Integer.parseInt(dest.toString() + source.toString());
if (isInRange(min, max, input))
return null;
} catch (NumberFormatException nfe) { }
return "";
}
这个显然是没有经过实际测试的代码。按照android的API source使用户本次输入的字符,dest是原有的字符串。但是,作者忽略了一个问题,用户未必每次都是在原来字符串的后面输入的,所以把source加到dest后面,并不正确。
就以IP地址输入为例,我先输入一个1, 这个时候dest="" source="1" 得到 input=1 这个是没有问题的
我在1后面再输入一个1, 这个时候dest="1" source="1" 得到input=11 这个也没有问题。
可是,第三个字符如果点一下EditText的前面,在字符串的最前方,输入一个8, 在这段代码中就会得到 desc="11" source="8" 结果input=118 而我实际输入的是 811 程序判断输入是合法的,但是实际上这却不是一个合法的IP地址。
要解决这个问题,实际上就需要考虑filter方法的其他几个参数了,而不是简单的把dest+source
在filter方法中第五个参数dstart 代表的是本次输入的字符,是在dest的那个位置输入的。所以用户真正输入的字符串,应该用一下的表达式来获取:
StringBuilder totalText=new StringBuilder();
totalText.append(destText.substring(0,dstart))
.append(sourceText)
.append(destText.substring(dstart,destText.length()));
当然, 大家用StringBuilder 还是用String相加那随便了。重点是,source出现的位置,并不总在dest后面,所以需要考虑用户的输入位置,因此需要借助dstart这个参数。
以下是完整的限制一个EditText只能输入0~255的inputfilter的例子,供大家参考:
public class IPSectionFilter implements InputFilter {
/**
* @param source 新输入的字符串
* @param start 新输入的字符串起始下标,一般为0
* @param end 新输入的字符串终点下标,一般为source长度-1
* @param dest 输入之前文本框内容
* @param dstart 新输入的字符在原字符串中的位置
* @param dend 原内容终点坐标,
* @return 输入内容
*/
@Override
public CharSequence filter(CharSequence source, int start, int end, Spanned dest, int dstart, int dend) {
String sourceText = source.toString();
String destText = dest.toString();
if(dstart==0 && "0".equals(source)){
//如果输入是0 且位置在第一位,取消输入
return "";
}
StringBuilder totalText=new StringBuilder();
totalText.append(destText.substring(0,dstart))
.append(sourceText)
.append(destText.substring(dstart,destText.length()));
try {
if (Integer.parseInt(totalText.toString()) > 255) {
return "";
}else if (Integer.parseInt(totalText.toString())==0){
//如果输入是0,取消输入
return "";
}
}
catch (Exception e){
return "";
}
if ("".equals(source.toString())){
return "";
}
return ""+Integer.parseInt(source.toString());
}
}
在EditText中加入这个filter即可
EditText edtIPSec1=findViewById(R.id.edtIPSec1);
edtIPSec1.setFilters(new InputFilter[]{new IPSectionFilter()});