Android监听EditText输入自动计算并更新另一EditText数值
现有代码的问题
你的实现存在3个会导致崩溃、功能异常的问题:
- 输入框内容为空、或输入非数字内容时,直接调用
Integer.parseInt()会抛出NumberFormatException触发闪退 - 调用
setText(totalAmount)时传入int类型参数,系统会将该值识别为字符串资源ID,去资源表查找对应内容,找不到就会抛出Resources.NotFoundException - 用int类型存储金额会丢失小数位,也容易出现计算精度误差,不符合金额类场景的常规开发要求
正确实现方案
建议将计算逻辑放到afterTextChanged回调中执行,同时增加空值、格式合法性校验,金额计算使用BigDecimal避免精度问题,参考代码如下:
// 可选:提前给输入框设置输入类型限制,仅允许输入数字和小数点,从源头减少非法输入 // binding.etTotalPrice.setInputType(InputType.TYPE_CLASS_NUMBER | InputType.TYPE_NUMBER_FLAG_DECIMAL); // binding.etReceivedPrice.setInputType(InputType.TYPE_CLASS_NUMBER | InputType.TYPE_NUMBER_FLAG_DECIMAL); binding.etReceivedPrice.addTextChangedListener(new TextWatcher() { @Override public void beforeTextChanged(CharSequence s, int start, int count, int after) {} @Override public void onTextChanged(CharSequence s, int start, int before, int count) {} @Override public void afterTextChanged(Editable s) { String totalPriceStr = binding.etTotalPrice.getText().toString().trim(); String receivedStr = s.toString().trim(); // 任意一个输入框为空时,清空计算结果,不执行后续逻辑 if (totalPriceStr.isEmpty() || receivedStr.isEmpty()) { binding.etTotalAmount.setText(""); return; } try { BigDecimal totalPrice = new BigDecimal(totalPriceStr); BigDecimal receivedAmount = new BigDecimal(receivedStr); BigDecimal result = totalPrice.subtract(receivedAmount); // 必须将计算结果转为字符串再传入setText,不要直接传数值类型 binding.etTotalAmount.setText(result.toPlainString()); } catch (NumberFormatException e) { // 输入内容格式非法时清空结果,避免崩溃 binding.etTotalAmount.setText(""); } } });
额外优化建议
- 如果总价输入框
etTotalPrice也支持用户编辑,需要给它也绑定相同的计算逻辑,保证任意一个输入框内容变化时都会触发重新计算 - 如果总金额栏仅用于展示计算结果、不允许用户修改,可以将其设置为不可编辑状态:
binding.etTotalAmount.setFocusable(false);,避免用户手动篡改结果导致数据错乱 - 如果业务要求金额固定保留2位小数,可以使用
DecimalFormat对结果格式化后再设置到控件上,例:new DecimalFormat("0.00").format(result)
内容的提问来源于stack exchange,提问作者Suleman Bajwa
相关产品推荐
相关产品推荐

