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

Android:如何用TextWatcher实现EditText的3位小数货币格式化

修改TextWatcher支持3位小数货币格式化

你的核心需求是把现有2位小数的货币格式化改成3位,同时保留输入时数值从右往左递进的逻辑(比如依次按1、2、3、4、5后显示12.345)。我直接给你修改后的完整代码,再拆解关键改动点:

完整修改后的代码

public class CurrencyTextWatcher implements TextWatcher {
    private boolean mEditing;
    private final DecimalFormat currencyFormat;

    public CurrencyTextWatcher() {
        mEditing = false;
        // 自定义格式化规则,强制3位小数,支持千位分隔
        currencyFormat = new DecimalFormat();
        currencyFormat.setMinimumFractionDigits(3);
        currencyFormat.setMaximumFractionDigits(3);
        currencyFormat.setGroupingUsed(true);
        // 如需固定货币符号,取消下面注释并指定对应Locale(比如Locale.CHINA对应¥)
        // currencyFormat.setCurrency(Currency.getInstance(Locale.getDefault()));
    }

    @Override
    public synchronized void afterTextChanged(Editable s) {
        if (!mEditing) {
            mEditing = true;

            // 提取所有数字字符,过滤非数字内容
            String digits = s.toString().replaceAll("\\D", "");
            // 处理空输入,默认显示初始值0.000
            if (digits.isEmpty()) {
                s.replace(0, s.length(), "0.000");
                mEditing = false;
                return;
            }

            try {
                // 用Long解析避免大数字的Double精度问题,除以1000得到3位小数数值
                long value = Long.parseLong(digits);
                double formattedValue = value / 1000.0;
                // 格式化后替换原文本
                String formatted = currencyFormat.format(formattedValue);
                s.replace(0, s.length(), formatted);
            } catch (NumberFormatException nfe) {
                // 异常情况重置为初始值
                s.replace(0, s.length(), "0.000");
            }

            mEditing = false;
        }
    }

    @Override
    public void beforeTextChanged(CharSequence s, int start, int count, int after) {
        // 无需额外处理
    }

    @Override
    public void onTextChanged(CharSequence s, int start, int before, int count) {
        // 无需额外处理
    }
}

关键改动说明

  • 调整除数为1000:原代码是将数字除以100(对应2位小数),现在改为除以1000,确保输入的数字串被解析为3位小数的数值(比如输入12345 → 12345/1000 = 12.345)。
  • 自定义DecimalFormat:放弃默认的NumberFormat.getCurrencyInstance()(它默认跟随系统小数位数,通常为2位),直接用DecimalFormat强制设置小数位数为3,保证格式统一。
  • 处理初始值/空输入:当EditText为空时自动填充0.000,满足你要求的初始值需求。
  • 用Long替代Double解析:避免大数字场景下Double的精度丢失问题(比如超长数字串出现科学计数法或误差)。

使用注意事项

  1. 初始化EditText:在布局或代码中给EditText设置初始值并绑定Watcher:
    EditText amountEt = findViewById(R.id.amount_edit_text);
    amountEt.setText("0.000");
    amountEt.addTextChangedListener(new CurrencyTextWatcher());
    
  2. 输入限制优化:建议给EditText设置输入类型为numberDecimal,提前限制非数字输入:
    <EditText
        android:id="@+id/amount_edit_text"
        android:inputType="numberDecimal"
        ... />
    

内容的提问来源于stack exchange,提问作者damith alahakoon

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.13 09:01:11