Android开发如何设置EditText输入类型为正整数或正小数?
Android EditText 限制输入正整数/正小数实现方案
原有配置无法生效的核心原因是:仅靠XML属性只能限制可输入的字符范围,无法校验字符组合的合法性,会出现多小数点、小数点开头、0123这类非法整数格式的问题。
1. 基础XML配置修正
首先将inputType替换为适配小数输入的系统类型,确保弹出纯数字键盘:
<EditText android:id="@+id/et_positive_number" android:layout_width="match_parent" android:layout_height="wrap_content" android:inputType="numberDecimal" android:digits="0123456789." android:hint="请输入正整数/正小数"/>
numberDecimal是系统专门为数字小数输入提供的类型,比基础number类型对小数输入的兼容性更好
2. 添加自定义输入过滤器拦截非法格式
XML属性无法覆盖组合规则校验,需要给EditText挂载InputFilter在输入过程中实时拦截非法内容,以下是可直接复用的代码:
Kotlin 实现
// 可根据需求修改小数点后保留位数,示例为保留2位 val positiveNumberFilter = InputFilter { source, _, _, dest, dstart, dend -> val newContent = buildString { append(dest.subSequence(0, dstart)) append(source) append(dest.subSequence(dend, dest.length)) } // 拦截以小数点开头的输入 if (newContent.startsWith(".")) return@InputFilter "" // 拦截多个小数点的输入 if (newContent.count { it == '.' } > 1) return@InputFilter "" // 拦截0开头的非小数格式(如012、001这类非法输入,允许0.xx格式) if (newContent.startsWith("0") && newContent.length > 1 && newContent[1] != '.') return@InputFilter "" // 拦截小数点后位数超标的输入,不需要可删除这段 if (newContent.contains(".")) { val dotIndex = newContent.indexOf('.') if (newContent.length - dotIndex - 1 > 2) return@InputFilter "" } // 兜底拦截非数字、非小数点的非法字符 if (!newContent.matches(Regex("^\\d*\\.?\\d*$"))) return@InputFilter "" null } // 给EditText设置过滤器,若有其他过滤器需一并加入数组,避免覆盖 et_positive_number.filters = arrayOf(positiveNumberFilter)
Java 实现
InputFilter positiveNumberFilter = new InputFilter() { @Override public CharSequence filter(CharSequence source, int start, int end, Spanned dest, int dstart, int dend) { StringBuilder newContent = new StringBuilder() .append(dest.subSequence(0, dstart)) .append(source) .append(dest.subSequence(dend, dest.length())); String contentStr = newContent.toString(); // 拦截小数点开头 if (contentStr.startsWith(".")) return ""; // 拦截多个小数点 long dotCount = contentStr.chars().filter(c -> c == '.').count(); if (dotCount > 1) return ""; // 拦截0开头的非法整数 if (contentStr.startsWith("0") && contentStr.length() > 1 && contentStr.charAt(1) != '.') return ""; // 拦截小数点后位数超标 if (contentStr.contains(".")) { int dotIndex = contentStr.indexOf("."); if (contentStr.length() - dotIndex - 1 > 2) return ""; } // 兜底拦截非法字符 if (!contentStr.matches("^\\d*\\.?\\d*$")) return ""; return null; } }; etPositiveNumber.setFilters(new InputFilter[]{positiveNumberFilter});
3. 可选:最终取值校验
如果需要覆盖极端定制ROM的兼容性问题,可以在提交输入内容时增加最终校验:
val inputVal = et_positive_number.text.toString().trim() val isInputValid = runCatching { val num = inputVal.toDouble() num > 0 // 确保为正数 }.getOrDefault(false) if (!isInputValid) { // 触发输入格式错误提示 }
内容的提问来源于stack exchange,提问作者dotcom
相关产品推荐
相关产品推荐

