You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

安卓开发如何禁止EditText输入多个小数点及开头输入小数点

问题原因

  1. 原有判断逻辑使用equals匹配正则规则完全无效,equals为字符串等值比对方法,不支持正则表达式匹配。
  2. 当输入内容仅为.时,直接调用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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.30 02:06:06