RecyclerView 局部刷新、删除错乱

列表的局部刷新和删除错乱问题尽管网上已经有很多牛人分享过解决方法,这里还是根据自己的实践记录一下吧。

一、局部刷新

有这样的场景,我们需要修改item中的某一要素,如:详情介绍,那么通常有以下几种方式:

1. Adapter.notifyDataSetChanged()
2. Adapter.notifyItemChanged(position)
3. Adapter.notifyItemChanged(position, payload)

下面分别介绍这几种使用的可行性

1、notifyDataSetChanged()

使用该方法会刷新当前列表可见Item,虽然能实现数据刷新,但是背离了我们的初衷(局部刷新),而且存在性能消耗,所以不建议使用

在这里插入图片描述

2020-07-28 11:25:27.192 I/RecyclerView: MineEntity{des='山西冰糖心苹果...', imgResId=2131558403}
2020-07-28 11:25:27.193 I/RecyclerView: MineEntity{des='刷新可见list。。。', imgResId=2131558404}
2020-07-28 11:25:27.195 I/RecyclerView: MineEntity{des='山西冰糖心苹果...', imgResId=2131558403}
2020-07-28 11:25:27.196 I/RecyclerView: MineEntity{des='正宗烟台脆甜苹果...', imgResId=2131558404}

可见,没触发一次notifyDataSetChanged()都会重新执行onBindViewHolder()绑定数据。

2、notifyItemChanged(position)

该方法能实现局部刷新,但是有个弊端,就是会刷新当前Item的全部数据,如果Item有图片,图片就会闪烁一下。
在这里插入图片描述

07-28 11:37:12.100 I/RecyclerView: MineEntity{des='山西冰糖心苹果...', imgResId=2131558403}
07-28 11:40:41.034 I/RecyclerView: MineEntity{des='图片闪烁。。。', imgResId=2131558403}
07-28 11:40:43.314 I/RecyclerView: MineEntity{des='图片闪烁。。。', imgResId=2131558403}
07-28 11:40:45.290 I/RecyclerView: MineEntity{des='图片闪烁。。。', imgResId=2131558403}

这下没有刷新可见Item了,只刷新了当前Item,但是存在图片闪烁问题,所以也不建议使用该方法。

3、notifyItemChanged(position, payload)

最终使用该方法,可以解决上面两种方法存在的问题,先看效果在这里插入图片描述

07-28 12:01:33.478 I/RecyclerView: MineEntity{des='山西冰糖心苹果...', imgResId=2131558403}
07-28 12:01:33.481 I/RecyclerView: payloads : false
07-28 12:01:36.196 I/RecyclerView: payloads : false
07-28 12:01:37.918 I/RecyclerView: payloads : false
07-28 12:01:38.852 I/RecyclerView: payloads : false

可以看到,图片不闪烁了,而且也不会刷新可见Item。使用也较为简单,实现RecyclerView.Adapter中带payloads参数的onBindViewHolder方法即可

3.1 onBindViewHolder带payloads参数方法实现
@Override
public void onBindViewHolder(@NonNull NewViewHolder holder, int position, @NonNull List<Object> payloads) {
    Log.i("RecyclerView","payloads : "+payloads.isEmpty());
    if (payloads.isEmpty()) {
        this.onBindViewHolder(holder, position);
    } else {
        for (Object object : payloads) {
            int payload = (int) object;
            if (payload == PAYLOAD_CODE) {
                holder.tvDes.setText(entityList.get(position).getDes());
            }
        }
    }
}

这里只是简单实现描述信息的修改。

3.2 notifyItemChanged(position, payload)方法调用
 mineEntity.setDes("时间 "+ TimeUtils.getNowString(new SimpleDateFormat("HH:mm:ss SSS", Locale.getDefault())));
 initList.set(position, mineEntity);
 mAdapter.notifyItemChanged(position, NewsAdapter.PAYLOAD_CODE);//优化局部刷新

只需以上两步,就能实现平时常见的图片闪烁问题和性能问题了。

二、删除Item发生错乱

平时做Item删除时,肯定有很多伙伴遇到过,明明自己想删掉Item2,结果Item3却被删掉了,而且删着删着应用还崩掉了。下面直接给正确用法。

//删除item
initList.remove(position);
mAdapter.notifyItemRemoved(position);
mAdapter.notifyItemRangeChanged(position, initList.size() - position);

欢迎关注我的个人微信公众号,【优了个秀】和你每天进步一点点
在这里插入图片描述

  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
RecyclerView的复用错乱问题是因为它的使用方式不正确所导致的。复用错乱是指在滑动RecyclerView时,列表项的数据与视图不匹配,在屏幕上显示的数据混乱或重复。 造成这个问题的常见原因有以下几点: 1. 数据源更新不及时:当数据源发生变化时,需要及时更新适配器的数据集。如果没有正确地处理数据源的变化,就会导致RecyclerView中的视图与数据不匹配。 2. 没有正确实现ViewHolder模式:RecyclerView通过重用ViewHolder来提高性能。如果没有正确实现ViewHolder模式,就会导致视图复用时数据混乱。正确的做法是在ViewHolder中设置视图的数据,而不是在绑定ViewHolder时修改视图的数据。 3. 使用了错误的布局管理器:布局管理器决定了RecyclerView中列表项的排列方式。如果使用了错误或不合适的布局管理器,就会导致列表项的位置混乱或错乱。 解决RecyclerView复用错乱问题的方法有以下几点: 1. 在数据源发生变化时,及时更新适配器的数据集,并调用适配器的notifyDataSetChanged方法,通知RecyclerView进行视图更新。 2. 确保正确实现ViewHolder模式,在ViewHolder中正确地设置视图的数据。 3. 注意选择合适的布局管理器,确保列表项的位置正确排列。 4. 可以使用一些开源库或框架,如DiffUtil或DataBinding等,来简化数据源更新和视图更新的过程。 总结起来,解决RecyclerView复用错乱问题的关键是正确处理数据源的更新、正确实现ViewHolder模式、选择合适的布局管理器,并注意使用相关的开源库或框架来简化开发过程。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值