如何为EditText设置输入掩码,限制输入最大值为20,999,999.99999999
当然可以实现!你之前想用InputFilter搭配正则的思路完全没问题,只是正则表达式需要调整得更精准,再加上数值范围的校验,就能完美满足需求。下面我一步步给你讲具体怎么弄:
实现方案:自定义InputFilter结合正则+数值校验
首先明确我们的核心输入规则:
- 整数部分最多8位,且不能超过20999999
- 小数部分最多7位,整体数值不能超过
20999999.99999999 - 禁止多个小数点、以小数点开头这类非法格式
1. 修正正则表达式
你之前的正则存在逻辑格式问题,没法精准匹配我们需要的范围。推荐使用下面的正则,它能覆盖所有合法输入场景:
^([1-9]\d{0,7}|20999999)(\.\d{0,7})?$|^0(\.\d{0,7})?$
简单解释下:
^([1-9]\d{0,7}|20999999):整数部分要么是1-8位(首位非0),要么是刚好20999999(\.\d{0,7})?$:可选的小数部分,最多7位|^0(\.\d{0,7})?$:允许输入0开头的小数(比如0.123这类合法场景)
2. 编写自定义InputFilter
正则只能校验格式,没法直接判断数值是否超过20999999.99999999这个边界值,所以我们需要在InputFilter里同时做格式校验和数值校验。
Kotlin版本代码
class MaxValueInputFilter : InputFilter { // 定义最大值,用BigDecimal避免Double精度丢失 private val maxValue = BigDecimal("20999999.99999999") private val pattern = Pattern.compile("^([1-9]\\d{0,7}|20999999)(\\.\\d{0,7})?$|^0(\\.\\d{0,7})?$") override fun filter( source: CharSequence?, start: Int, end: Int, dest: Spanned?, dstart: Int, dend: Int ): CharSequence? { // 拼接用户输入后的完整文本 val newText = buildString { append(dest?.subSequence(0, dstart)) append(source?.subSequence(start, end)) append(dest?.subSequence(dend, dest.length)) } // 空输入直接放行 if (newText.isEmpty()) return null // 第一步:校验格式是否符合正则 val matcher = pattern.matcher(newText) if (!matcher.matches()) return "" // 第二步:校验数值是否超过最大值 return try { val inputValue = BigDecimal(newText) if (inputValue > maxValue) "" else null } catch (e: NumberFormatException) { // 兜底处理异常格式(正则已经拦截,这里是双重保障) "" } } }
Java版本代码
public class MaxValueInputFilter implements InputFilter { private final BigDecimal maxValue = new BigDecimal("20999999.99999999"); private final Pattern pattern = Pattern.compile("^([1-9]\\d{0,7}|20999999)(\\.\\d{0,7})?$|^0(\\.\\d{0,7})?$"); @Override public CharSequence filter(CharSequence source, int start, int end, Spanned dest, int dstart, int dend) { StringBuilder newText = new StringBuilder(); newText.append(dest.subSequence(0, dstart)); newText.append(source.subSequence(start, end)); newText.append(dest.subSequence(dend, dest.length())); String input = newText.toString(); if (input.isEmpty()) return null; Matcher matcher = pattern.matcher(input); if (!matcher.matches()) return ""; try { BigDecimal inputValue = new BigDecimal(input); if (inputValue.compareTo(maxValue) > 0) { return ""; } } catch (NumberFormatException e) { return ""; } return null; } }
3. 给EditText设置Filter
最后把自定义的Filter绑定到你的EditText上,记得清空默认Filter避免冲突:
Kotlin
yourEditText.filters = arrayOf(MaxValueInputFilter())
Java
yourEditText.setFilters(new InputFilter[]{new MaxValueInputFilter()});
额外注意点
- 我用了
BigDecimal而不是Double来做数值比较,是因为Double在处理超长小数时会有精度丢失问题,用BigDecimal能保证数值判断绝对准确。 - 如果你的需求允许输入千位分隔符(比如
20,999,999.99),需要在Filter里先移除逗号再做校验,正则也需要对应调整。
内容的提问来源于stack exchange,提问作者Collins
相关产品推荐
相关产品推荐

