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

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.17 12:40:34