如何修改Currency EditText的输入行为?自定义货币输入逻辑需求咨询
修改CurrencyEditText库实现自定义输入逻辑
我之前研究过这个库的源码,刚好能帮你解决这个强制补全小数位的问题!核心是要调整它的数字解析逻辑和格式化规则,让它支持手动输入小数点,并且不再强制补全末尾的零。下面是具体的修改步骤:
1. 调整输入过滤器,允许手动输入小数点
找到库中的CurrencyInputFilter类(通常在com.faranjit.currencyedittext.filter包下),修改它的filter方法,允许输入小数点,同时限制只能输入一个:
@Override public CharSequence filter(CharSequence source, int start, int end, Spanned dest, int dstart, int dend) { String decimalSeparator = currencyEditText.getDecimalSeparator(); // 允许删除操作 if (source.toString().isEmpty()) { return null; } // 检查是否是小数点 if (source.toString().equals(decimalSeparator)) { // 如果已有小数点,过滤掉新的 if (dest.toString().contains(decimalSeparator)) { return ""; } // 允许输入小数点 return null; } // 只允许数字和小数点(已经处理过小数点的情况) if (!source.toString().matches("[0-9]")) { return ""; } return super.filter(source, start, end, dest, dstart, dend); }
2. 修改文本监听类的数字解析逻辑
找到CurrencyTextWatcher类(通常在com.faranjit.currencyedittext.watcher包下),重写它的afterTextChanged方法,让它能识别手动输入的小数点,不再把所有输入当成整数位:
@Override public void afterTextChanged(Editable s) { currencyEditText.removeTextChangedListener(this); String originalText = s.toString(); String decimalSeparator = currencyEditText.getDecimalSeparator(); // 提取数字和小数点,去掉其他符号 String cleanedText = originalText.replaceAll("[^0-9" + Pattern.quote(decimalSeparator) + "]", ""); BigDecimal amount; int decimalPosition = cleanedText.indexOf(decimalSeparator); if (decimalPosition != -1) { // 分割整数和小数部分 String integerPart = cleanedText.substring(0, decimalPosition).replaceAll("\\D", ""); String decimalPart = cleanedText.substring(decimalPosition + 1).replaceAll("\\D", ""); // 最多保留两位小数,避免输入过多 if (decimalPart.length() > 2) { decimalPart = decimalPart.substring(0, 2); } // 合并成完整数字字符串,计算实际金额 String fullDigits = integerPart + decimalPart; amount = new BigDecimal(fullDigits).divide(new BigDecimal(Math.pow(10, decimalPart.length()))); } else { // 没有小数点,直接作为整数处理 String integerDigits = cleanedText.replaceAll("\\D", ""); amount = integerDigits.isEmpty() ? BigDecimal.ZERO : new BigDecimal(integerDigits); } // 格式化显示文本 NumberFormat currencyFormat = NumberFormat.getCurrencyInstance(currencyEditText.getLocale()); // 根据金额是否有小数部分调整显示格式 if (amount.stripTrailingZeros().scale() <= 0) { // 没有小数部分,显示整数格式 currencyFormat.setMaximumFractionDigits(0); } else { // 有小数部分,显示对应位数(最多两位) currencyFormat.setMinimumFractionDigits(1); currencyFormat.setMaximumFractionDigits(2); } String formattedText = currencyFormat.format(amount); s.replace(0, s.length(), formattedText); // 恢复光标位置(避免格式化后光标跳到开头) int cursorPosition = formattedText.length(); if (originalText.endsWith(decimalSeparator) && !formattedText.endsWith(decimalSeparator)) { cursorPosition += 1; } currencyEditText.setSelection(Math.min(cursorPosition, formattedText.length())); currencyEditText.addTextChangedListener(this); }
3. 测试调整后的逻辑
修改完代码后,重新编译库并集成到你的项目中,测试以下场景:
- 输入
1→ 显示$1(根据你的地区货币符号自动调整) - 输入
1.5→ 显示$1.5 - 输入
1.50→ 显示$1.50(如果需要保留末尾零,可以调整格式化规则) - 删除数字时,能正确回退格式(比如从
$1.5删除5后变成$1)
额外优化建议
如果你希望用户输入小数点后最多只能输入两位数字,可以在CurrencyInputFilter中进一步限制小数部分的长度,避免用户输入过多无效位数。
内容的提问来源于stack exchange,提问作者yigitserin
相关产品推荐
相关产品推荐

