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的精度丢失问题(比如超长数字串出现科学计数法或误差)。
使用注意事项
- 初始化EditText:在布局或代码中给EditText设置初始值并绑定Watcher:
EditText amountEt = findViewById(R.id.amount_edit_text); amountEt.setText("0.000"); amountEt.addTextChangedListener(new CurrencyTextWatcher()); - 输入限制优化:建议给EditText设置输入类型为
numberDecimal,提前限制非数字输入:<EditText android:id="@+id/amount_edit_text" android:inputType="numberDecimal" ... />
内容的提问来源于stack exchange,提问作者damith alahakoon
相关产品推荐
相关产品推荐

