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

如何修改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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.26 11:01:25