Android EditText 限制只能输入指定范围的数字

最近由于公司需要,改做一个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()});

 

  • 3
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 6
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 6
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值