安卓开发如何禁止EditText输入多个小数点及开头输入小数点
问题原因
- 原有判断逻辑使用
equals匹配正则规则完全无效,equals为字符串等值比对方法,不支持正则表达式匹配。 - 当输入内容仅为
.时,直接调用toDouble()方法会抛出未捕获的NumberFormatException异常,触发应用崩溃。
正确实现方案
方案一:使用InputFilter(推荐,输入阶段直接拦截非法内容,体验更好)
自定义输入过滤器在输入前完成规则校验,拦截不符合要求的输入,无需后续回删处理:
// 自定义小数输入过滤器 val decimalInputFilter = InputFilter { source, start, end, dest, dstart, dend -> // 拼接得到输入完成后的完整字符串 val fullText = dest.subSequence(0, dstart).toString() + source.subSequence(start, end) + dest.subSequence(dend, dest.length) // 规则1:禁止内容开头为小数点 if (fullText.startsWith(".")) { return@InputFilter "" } // 规则2:禁止出现超过1个小数点 if (fullText.count { it == '.' } > 1) { return@InputFilter "" } // 符合规则不拦截输入 null } // 给EditText设置过滤器,合并数字字符限制规则与自定义小数校验规则 et_cm.filters = arrayOf( decimalInputFilter, DigitsKeyListener.getInstance("1234567890.") )
使用该方案后,布局中的android:digits属性可移除,避免规则重复。
方案二:修改原有TextWatcher逻辑
如果不需要调整输入拦截逻辑,可直接修改原有TextWatcher的校验规则:
et_cm.addTextChangedListener(object : TextWatcher { override fun beforeTextChanged(s: CharSequence, start: Int, count: Int, after: Int) {} override fun onTextChanged(s: CharSequence, start: Int, before: Int, count: Int) { if (et_cm.hasFocus()) { val inputContent = s.toString() // 处理开头输入小数点的情况 if (inputContent.startsWith(".")) { et_cm.setText("") return } // 处理多个小数点的情况 val dotCount = inputContent.count { it == '.' } if (dotCount > 1) { val lastDotPos = inputContent.lastIndexOf('.') val fixedContent = inputContent.removeRange(lastDotPos, lastDotPos + 1) et_cm.setText(fixedContent) et_cm.setSelection(fixedContent.length) return } // 单位转换逻辑增加异常规避 if (inputContent.isEmpty() || inputContent == ".") { et_inches.setText("0") } else { val cmValue = inputContent.toDouble() val inchValue = ConvertCmToInch(cmValue).toString() et_inches.setText(inchValue) } } } override fun afterTextChanged(s: Editable) {} })
内容的提问来源于stack exchange,提问作者Gonçalo Carvalho
相关产品推荐
相关产品推荐

