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

RecyclerView条目点击切换图片异常问题求助(附Adapter代码)

问题分析与解决方案

你的问题根源在于RecyclerView的ViewHolder复用机制,以及未将收藏状态与数据模型绑定,直接操作View导致状态混乱:

  • 点击条目时仅修改当前ViewHolder的图片,未同步更新数据模型,滚动时复用的ViewHolder会保留之前的状态,出现图片乱变。
  • 每次onBindViewHolder都创建DatabaseHandler实例,造成资源浪费。
  • 未在onBindViewHolder中根据数据库状态初始化图片,导致复用的View显示错误状态。

具体修复步骤

1. 给数据模型添加状态字段

在RepairItems类中添加布尔字段,标记当前条目是否已加入收藏:

public class RepairItems {
    // 原有字段...
    private boolean isWishlisted;

    // 添加getter和setter
    public boolean isWishlisted() {
        return isWishlisted;
    }

    public void setWishlisted(boolean wishlisted) {
        isWishlisted = wishlisted;
    }
}

2. 初始化Adapter时同步收藏状态

在Adapter构造函数中,从数据库读取已收藏条目,更新对应RepairItems的状态:

public RepairItemsAdapter(Context context, List<RepairItems> doctorsList, ContactsAdapterListener listener) {
    this.context = context;
    this.listener = listener;
    this.doctorsList = doctorsList;
    this.doctorsListFiltered = new ArrayList<>(doctorsList); // 避免直接引用同一集合
    this.db = new DatabaseHandler(context); // 仅初始化一次数据库实例

    // 初始化收藏状态
    for (RepairItems item : doctorsList) {
        item.setWishlisted(db.getWishlist(item.getProduct_id()) != null);
    }
}

3. 修改onBindViewHolder,根据状态设置图片

在onBindViewHolder中,根据数据模型状态设置图片,同时优化点击事件:

@Override
public void onBindViewHolder(MyViewHolder holder, final int position) {
    final RepairItems cat_main = doctorsListFiltered.get(position);
    holder.cat_name.setText(cat_main.getProducts_title());
    holder.cat_id.setText(cat_main.getProduct_id());
    holder.price.setText(cat_main.getProducts_price());

    // 根据数据模型状态设置图片
    if (cat_main.isWishlisted()) {
        holder.my_checkbox.setImageResource(R.drawable.ic_check_box_checked);
    } else {
        holder.my_checkbox.setImageResource(R.drawable.ic_check_box_empty);
    }

    holder.linear.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View view) {
            boolean currentState = cat_main.isWishlisted();
            if (currentState) {
                // 已收藏,执行删除
                db.deleteWishlist(Long.valueOf(cat_main.getProduct_id()));
                cat_main.setWishlisted(false);
            } else {
                // 未收藏,执行添加
                Wishlist w = new Wishlist(Long.parseLong(cat_main.getProduct_id()), 
                                         cat_main.getProduct_id(), 
                                         cat_main.getProducts_title(), 
                                         Integer.parseInt(cat_main.getProducts_price()));
                db.saveWishlist(w);
                cat_main.setWishlisted(true);
            }
            // 仅刷新当前条目,避免整个列表重绘
            notifyItemChanged(position);
        }
    });
}

4. 修复Filter中的状态同步

在Filter的performFiltering方法中,保留原数据的收藏状态:

@Override
protected FilterResults performFiltering(CharSequence charSequence) {
    String charString = charSequence.toString();
    List<RepairItems> filteredList = new ArrayList<>();
    if (charString.isEmpty()) {
        filteredList.addAll(doctorsList);
    } else {
        for (RepairItems row : doctorsList) {
            if (row.getProducts_title().toLowerCase().contains(charString.toLowerCase())) {
                filteredList.add(row);
            }
        }
    }

    FilterResults filterResults = new FilterResults();
    filterResults.values = filteredList;
    return filterResults;
}

额外优化建议

  • 避免在onBindViewHolder中重复创建点击事件,可将点击事件移到MyViewHolder构造函数中,通过getAdapterPosition()获取当前位置。
  • 数据库操作建议放在异步线程中执行,避免阻塞UI线程。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.23 02:38:01