RecyclerView商品数量增减崩溃及价格计算异常排查求助
问题排查与修复方案
崩溃原因分析
从日志能定位两个核心错误,同时代码存在逻辑漏洞:
- NumberFormatException:价格是带小数的字符串(如
"110.8500"),用Integer.parseInt()解析整数必然报错,小数不属于合法整数字符串格式。 - Resources$NotFoundException:直接将计算后的整数传给
setText(),Android会把该整数当作资源ID去查找字符串资源,找不到就触发崩溃,必须先转成字符串再设置。 - 数量逻辑错误:增量按钮里的
numVal = number++是后置自增,导致numVal拿到的是自增前的数值,总价计算用错了数量。 - ViewHolder复用问题:每次
onBindViewHolder强制把数量设为"1",RecyclerView滚动时会重置之前修改的数量;全局number变量会被多个item共享,点击时出现数量混乱。
代码修复与总价计算修正
1. 修正价格解析与总价计算
将价格解析为浮点类型,计算后格式化字符串再设置到TextView:
holder.brd_increment.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { String quantityStr = holder.brd_quantity.getText().toString().trim(); if(quantityStr.isEmpty()){ Toast.makeText(v.getContext(), "Quantity cannot be empty", Toast.LENGTH_SHORT).show(); return; } int number = Integer.parseInt(quantityStr); if(number >= 9999){ Toast.makeText(v.getContext(), "Quantity cannot be greater than 9999", Toast.LENGTH_SHORT).show(); return; } number++; holder.brd_quantity.setText(String.valueOf(number)); // 解析价格并计算总价,处理格式异常 try { double price = Double.parseDouble(product.getBrdprice()); double totalPrice = price * number; // 格式化总价为两位小数 holder.brd_value.setText(String.format("%.2f", totalPrice)); } catch (NumberFormatException e) { holder.brd_value.setText("0.00"); Toast.makeText(v.getContext(), "Invalid price format", Toast.LENGTH_SHORT).show(); } } });
2. 修正减量按钮逻辑
同步更新总价,避免数量异常:
holder.brd_decrement.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { String quantityStr = holder.brd_quantity.getText().toString().trim(); if(quantityStr.isEmpty()){ Toast.makeText(v.getContext(), "Quantity cannot be empty", Toast.LENGTH_SHORT).show(); return; } int number = Integer.parseInt(quantityStr); if(number <= 1){ Toast.makeText(v.getContext(), "Quantity cannot be less than 1", Toast.LENGTH_SHORT).show(); number = 1; } else { number--; } holder.brd_quantity.setText(String.valueOf(number)); // 同步计算并更新总价 try { double price = Double.parseDouble(product.getBrdprice()); double totalPrice = price * number; holder.brd_value.setText(String.format("%.2f", totalPrice)); } catch (NumberFormatException e) { holder.brd_value.setText("0.00"); Toast.makeText(v.getContext(), "Invalid price format", Toast.LENGTH_SHORT).show(); } } });
3. 解决ViewHolder复用问题
在数据模型中存储数量,避免滚动重置:
@Override public void onBindViewHolder(@NonNull RVOrderBrdAdapter.RVViewHolder holder, int position) { OrderBrdDataModel product = filteredList.get(position); holder.brd_product.setText(product.getBrdname()); // 初始化数量:从数据模型读取,无数据则设为1 if(product.getQuantity() == null || product.getQuantity() <= 0){ product.setQuantity(1); } holder.brd_quantity.setText(String.valueOf(product.getQuantity())); // 初始化显示总价 try { double price = Double.parseDouble(product.getBrdprice()); double totalPrice = price * product.getQuantity(); holder.brd_value.setText(String.format("%.2f", totalPrice)); } catch (NumberFormatException e) { holder.brd_value.setText("0.00"); } // 增量、减量按钮事件使用上面修正后的代码 }
需要在OrderBrdDataModel中添加数量字段及对应方法:
public class OrderBrdDataModel { private String brdname; private String brdprice; private Integer quantity; // 新增数量字段 // 原有getter/setter方法 public String getBrdname() { return brdname; } public void setBrdname(String brdname) { this.brdname = brdname; } public String getBrdprice() { return brdprice; } public void setBrdprice(String brdprice) { this.brdprice = brdprice; } // 数量的getter/setter public Integer getQuantity() { return quantity; } public void setQuantity(Integer quantity) { this.quantity = quantity; } // 原有isSelected相关方法... }
4. 移除全局变量
删除全局的number和numVal变量,每个item的数量存储在对应的数据模型中,避免多item互相干扰。
总结
- 用
Double.parseDouble()解析带小数的价格,避免数字格式异常。 - 设置TextView文本时,必须将数字转为字符串(
String.valueOf()或String.format()),避免触发资源查找崩溃。 - 将数量存储在数据模型中,解决RecyclerView复用导致的数量重置问题。
- 修正自增逻辑,避免后置自增带来的数值错误。
内容的提问来源于stack exchange,提问作者Abm
相关产品推荐
相关产品推荐

