有关RecyclerView.Adapter 的 notifyItemChanged(int position, @Nullable Object payload) 方法

RecyclerView notifyItemChanged 之后的源码分析 i >= 0;//注释1处,记录动画之后的所有ViewHolder信息 animationInfo,保存到 mViewInfoStore 中//注释2处,之前变化的ViewHolder的动画信息。= null &&!// 保存到 mViewInfoStore 中} else {//变化的ViewHolder,之前的动画信息//注释3处,变化的ViewHolder之后的动画信息添加到 mViewInfoStore 中。 阅读详情

今天在看某个项目的源码的时候,无意间看到了 RecyclerView.Adapter 的 notifyItemChanged(int position, @Nullable Object payload) 方法,以前没有见过,后来自己查来之后,才知道这个是与 RV 的 Item 局部刷新有关的。

平时一般是用 notifyItemChanged(int position) 方法来进行局部刷新,但是这个局部刷新是通过回调 onBindViewHolder(@NonNull VH holder, int position) 该方法刷新指定的 item 的整个视图,如果该视图里面包含图片什么的,如果逻辑处理不当会导致图片也被重新刷新而使视图在效果闪一下。

而如果使用 notifyItemChanged(int position, @Nullable Object payload) 方法的话,则会回调 onBindViewHolder(@NonNull VH holder, int position,@NonNull List<Object> payloads) 方法,然后再该方法中就可以使用 payloads 参数来进行布局的刷新。


先用一个实例来演示一下:
假设 RV 中的 Item 包括一个 ImageView、两个 TextView,然后整个 Item 设置了一个点击事件,当 Item 被点击之后,就要为内部对应的两个 TextView 更新一下文本信息,如下图所示:
这里写图片描述

然后是省略之后的主要代码:

public class MyAdapter extends RecyclerView.Adapter<MyAdapter.ViewHolder> {
    private List<ItemBean> data;

    ......

    @Override
    public void onBindViewHolder(ViewHolder holder, int position) {
        ItemBean itemBean=data.get(position);
        holder.tv1.setText(itemBean.str1);
        holder.tv2.setText(itemBean.str2);
        holder.iv.setImageResource(R.mipmap.ic_launcher);
    }

    //要注意,当上下滑动 RV 导致 Item 因复用更新视图时,也会走该方法的,但是此时 payloads 为空
    //所以应该注意在该方法中刷新的状态应该保存到 data 对应的 bean 中,使更新时能够读取到正确的状态而展现出正确的效果
    //否则在上下滑动后,原位置的 Item 效果会退回到局部更新之前
    @Override
    public void onBindViewHolder(ViewHolder holder, int position, List<Object> payloads) {
        if (payloads.isEmpty()) {
            //payloads 为 空,说明是更新整个 ViewHolder 
            onBindViewHolder(holder, position);
        } else {
            ItemBean itemBean=data.get(position);
            //将需要刷新的状态保存到 ItemBean 对应的成员变量中
            itemBean.str1 += (String) payloads.get(0);
            itemBean.str2 += (String) payloads.get(1);
            holder.tv1.setText(itemBean.str1);
            holder.tv2.setText(itemBean.str2);
        }
    }

    class ViewHolder extends RecyclerView.ViewHolder {
        final TextView tv1,tv2;
        final ImageView iv;

        public ViewHolder(View itemView) {
            super(itemView);
            tv1 = itemView.findViewById(R.id.tv1);
            tv2 = itemView.findViewById(R.id.tv2);
            iv = itemView.findViewById(R.id.iv);
            itemView.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    notifyItemChanged(getAdapterPosition()," update for 1");
                    notifyItemChanged(getAdapterPosition()," update for 2");
                }
            });
        }
    }
}

这里需要注意的是,在 onBindViewHolder(ViewHolder holder, int position, List<Object> payloads) 中布局刷新时,同时需要将刷新的状态保存到对应的 bean 中,否则在上下滑动后,原 position 位置的 item 会退回到未局部刷新之前的状态。就像下图的效果:
这里写图片描述

@Override
    public void onBindViewHolder(ViewHolder holder, int position, List<Object> payloads) {
        if (payloads.isEmpty()) {
            onBindViewHolder(holder, position);
        } else {
            ItemBean itemBean=data.get(position);
//            itemBean.str1 += (String) payloads.get(0);
//            itemBean.str2 += (String) payloads.get(1);
//            holder.tv1.setText(itemBean.str1);
//            holder.tv2.setText(itemBean.str2);
            //直接刷新该局部视图,而不保存相应的状态到 bean 中
            holder.tv1.setText(itemBean.str1 + payloads.get(0));
            holder.tv2.setText(itemBean.str2 + payloads.get(1));
        }
    }

之后,需要补充几点:

1、如果重写了 onBindViewHolder(ViewHolder holder, int position, List<Object> payloads) 方法,那么不管是 RV 在初始化时,还是在因为上下滑动而刷新时,都会走该方法(此时 payloads 为空),而不走 onBindViewHolder(ViewHolder holder, int position) 方法,因此,需要完善逻辑,在 payloads 为空时手动调用 onBindViewHolder(holder, position); 或者将原本 onBindViewHolder(holder, position); 的逻辑写到这里。

2、每一个具体的 position 都会在 onBindViewHolder(holder, position, payloads) 方法对应一个单独的 payloads 。
这一点测试一下即可知道,假设为 ItemView 的点击事件补充如下代码:

itemView.setOnClickListener(new View.OnClickListener() {
    @Override
    public void onClick(View v) {
        notifyItemChanged(getAdapterPosition()," update for 1 ->"+getAdapterPosition());
        notifyItemChanged(getAdapterPosition()," update for 2 ->"+getAdapterPosition());
        //补充的代码
        notifyItemChanged(getAdapterPosition()+1," update for 1 ->"+(getAdapterPosition()+1));
        notifyItemChanged(getAdapterPosition()+1," update for 2 ->"+(getAdapterPosition()+1));
    }
});

则可以看到如下的效果:
这里写图片描述
position 为 1 和 2 分别刷新了对应的视图,且两者没有交叉。

3、假设在 notifyItemChanged(position, payload) 方法中传入的 payload 为 null,则会把 position 对应的 List<Object> payloads 清空,而在调用 onBindViewHolder(ViewHolder,int,List) 之前 notifyItemChanged(position, payload) 将不会起作用。
这个可以在源码的注释中了解到。
这里写图片描述
其中标记处的大致意思是:
notifyItemRangeChanged()中 payload == null 时将清除该项目上的所有现有的 payloads,并阻止将来
payloads 增加元素,直到调用 onBindViewHolder(ViewHolder,int,List)

然后通过实测也可以验证:

itemView.setOnClickListener(new View.OnClickListener() {
    @Override
    public void onClick(View v) {
        notifyItemChanged(getAdapterPosition()," update for 1 ->"+getAdapterPosition());
        notifyItemChanged(getAdapterPosition()," update for 2 ->"+getAdapterPosition());
        notifyItemChanged(getAdapterPosition(),null);
        notifyItemChanged(getAdapterPosition()," update for 3 ->"+getAdapterPosition());
        notifyItemChanged(getAdapterPosition()," update for 4 ->"+getAdapterPosition());
    }

将 ItemView 的点击事件改成上述,然后运行,点击 Item,此时虽然会调用 onBindViewHolder(ViewHolder,int,List) ,但是 payloads.size() == 0。

4、连续多次的调用 notifyItemChanged(position, payload),但是只会回调一次
onBindViewHolder(ViewHolder,int,List)。具体原因需要分析源码,目前暂不深究。

Android进阶之解决RecyclerView notifyItem闪屏问题 1 RecyclerView刷新方法1.1操作内容ListView的getView方法的渲染数据部分的代码相当于onBindViewHolder(),如果调用adapter.notifyDataSetChanged()方法,会重新调用onBindViewHolder()方法。1.2其他刷新方法除了adapter.notifyDataSetChanged()这个方法之外,新的Adapter还提供了其他 阅读详情

相关推荐

Android知识点-RecyclerView notifyItemChanged(position)返回ViewHolder数据有误

现象   常在路边走,哪有不湿鞋。   这不就有一个需求,让做一个列表的单条目刷新,多简单的一个需求啊,简简单单的CV之后,代码就敲完了,然后手贱了一小下,做了个自测,然后,悲剧就这么出现了。   具体需求我已经记不住了,这里模拟一下类似的情况,自定义一个ViewHolder,其中有一个参数count,用于记录当前ViewHolder刷新了多少次,然后通过TextView展示出来即可。   布局: <?xml version="1.0" encoding="utf-8"?> <Linear

半寿翁的博客 3139

recycleView局部更新item notifyItemChanged()几个方法区别

一直只知道recycleview局部刷新就想到notifyItemchanged()方法,里面传入position即可,用起来的时候是方便,但有时候却不能满足现在的需求,于是就百度。 先看几个常用的刷新方法 notifyDataSetChanged(), notifyItemChanged(int position) 这两个是再不能常见的。 notifyDataSetChanged(...

qq_34900897的博客 1万+

5分钟搞定!用L型匹配电路优化窄带天线性能(附Smith圆图实操)

本文针对窄带天线阻抗匹配难题,提供了一套5分钟快速解决方案。通过详解L型匹配电路的核心原理,并结合Smith圆图这一射频工程师的“瑞士军刀”,手把手指导如何选择拓扑、计算元件值并进行实际调试,旨在帮助硬件工程师高效优化天线性能,实现最大功率传输。

yyy34的博客 443

Android之RecyclerView巧用payload实现局部刷新

在使用RecyclerView 的过程中,可以调用Adapter以下方法,实现视图刷新: notifyItemChanged(int position, @Nullable Object payload) 对指定位置的item重新布局显示payload:可选参数,使用null时等同notifyItemChanged(int position) notifyItemChanged(...

LVXIANGAN的专栏 9176

做小程序支付时,我是怎么被“虚拟支付”绊了一跤的

微信小程序支付开发中,普通支付与虚拟支付存在本质差异。开发者常误将虚拟权益(会员、点数等)当作普通商品支付,导致审核失败。两者在审核关注点、结算方式、API调用及平台政策上都截然不同。关键点在于:1)先明确交易对象类型;2)产品命名需真实反映权益性质;3)支付成功≠业务完成;4)审核说明要详细描述交付逻辑;5)避免依赖过时规则。正确顺序应是:判断商品属性→选择支付类型→设计订单系统→准备审核材料。这个认知差异比技术实现更重要,提前理解平台规则可大幅减少返工。

zhurizhe71的学习之路 2577

某智能物流无人值守系统 ExportReport SQL注入漏洞复现

某智能物流无人值守系统 ExportReport存在SQL注入漏洞,未经身份验证的远程攻击者除了可以利用 SQL 注入漏洞获取数据库中的信息(例如,管理员后台密码、站点的用户个人信息)之外,甚至在高权限的情况可向服务器中写入木马,进一步获取服务器系统权限。

0xSec 818

android局部刷新fb,RecyclerView - 的 payload,实现局部刷新

在RecyclerView的源码里,有如下方法:public void onBindViewHolder(VHholder, int position, List payloads) {onBindViewHolder(holder, position);}该函数不是abstract的,所以容易被忽视,但是,其中payloads参数,可以实现RecyclerView的局部刷新.如果你的Recycl...

weixin_30224231的博客 832

【实战圣经】YOLOv8-pose姿态估计模型从训练到RK3588部署:让边缘端骨骼识别速度突破60FPS

本教程从“模型训练-转换-边缘部署”全链路拆解了YOLOv8-pose姿态估计方案在RK3588上的落地过程,每一步都经过实战验证。无论是智能健身的动作实时纠正,还是工业设备的关键部件姿态检测,这套流程都能让你以最低成本实现高精度、高实时性的姿态估计应用。如果你在实践中遇到模型转换报错、部署性能不达标等问题,可聚焦某一环节深入优化——毕竟,让AI在边缘端“精准捕捉每一个关键点”,才是技术驱动场景创新的核心。

m0_71589036的博客 251

RecyclerView刷新与加载的底层原理与性能优化实战

RecyclerView是Android列表渲染的核心组件,其刷新与加载机制远不止调用notifyDataSetChanged或add数据那么简单。本质上,它是数据源、视图状态与动画控制器三者间的状态同步过程,依赖Adapter、LayoutManager、ViewHolder复用及DiffUtil等模块协同工作。合理运用DiffUtil可实现增量更新,避免全量重绑导致的卡顿;结合滚动状态机(SCROLL_STATE_IDLE)与防抖策略,能保障上拉加载的精准触发。这些技术不仅提升帧率、降低内存占用,更直接

weixin_34320724的博客 313

MATLAB基础应用精讲-【数模应用】信用评分模型(附R语言和python代码实现)

信用评分模型是近年来兴起的一种为了保障银行和其他金融部门的金融安全而设立的一种关于人身金融权限的划定模型。该模型指根据客户的信用历史资料,利用一定的信用评分模型,得到不同等级的信用分数,根据客户的信用分数,来决定客户所可以持有的金额权限,从而保证还款等业务的安全性。而随着在现代社会和公司中,贷款,信用卡的作用日渐突出,信用评分模型的发展前景不可估量。信贷风险是指借款人因偿还贷款或履行合同承诺而破产而产生损失的可能性。传统上,它与贷款人无法偿还所欠利息和本金、影响现金流和增加装配成本所产生的风险有关。

qq_36130719的博客 364

YOLOv11改进策略【独家融合改进】| 模型轻量化二次改进:StarNet + FreqFusion,极限降参,适用专栏内所有轻量化模型

FreqFusion是一种旨在解决密集图像预测任务中特征融合问题。

Limiiiing的博客 2123

从深夜轰鸣到耳语:FanControl风扇控制完整实操指南

凌晨三点,对局正酣,机箱突然像一台加力的涡轮发动机;负载一掉,风扇又戛然而止。这种反复横跳,是主机最劝退的时刻。根源往往不在硬件,而在 BIOS 里那套一刀切的默认策略。你需要的是 FanControl——免费、免安装、占用极低的 Windows 10/11 风扇控制工具,每条转速曲线都由你自己来画,也是 Windows 散热优化里性价比最高的一步。 **拿到并启动。** 仓库里直接带了 `Fa

gitblog_00367的博客 195

YOLOv9改进策略【注意力机制篇】| 添加SE、CBAM、ECA、CA、Swin Transformer等注意力和多头注意力机制

这篇文章带来一个经典注意力模块的汇总,虽然有些模块已经发布很久了,但后续的注意力模块也都是在此基础之上进行改进的,对于初学者来说还是有必要去学习了解一下,以加深对模块,模型的理解。

Limiiiing的博客 2890

FlexibleAdapter架构深度解析:RecyclerView性能优化与实现原理

FlexibleAdapter作为Android RecyclerView适配器的革命性解决方案,通过精心设计的架构将多种复杂功能整合到单一库中,为开发者提供了卓越的用户体验。本文将从架构设计、实现原理和性能优化三个维度,深入剖析FlexibleAdapter的技术核心,为中级和高级开发者提供深度的技术参考。 ## 架构设计思想:分层解耦与职责分离 FlexibleAdapter采用了经典的三

gitblog_00874的博客 495

Open3d (C++) RANSAC拟合圆柱(详细过程版)

实现了一种基于RANSAC算法的圆柱拟合方法。

点云侠的博客 237

C# WinForm 基于DirectShow.dll编写的程序,可边预览边保存视频,音频和图片

基于微软的DirectShow.dll的二次开发1.自动识别连接的摄像头跟麦克风且可以对其进行选择(默认选中第一个)2.可录制wmv和avi两种格式的视频并且都带有音频,avi可以录制的分辨率和帧数进行选择,wmv默认进行了淸晰度优化如不喜欢可去除代码中有相关提示3.可在预览点开之后进行拍照,也可边录制视频边拍照4.添加了视频和音频的压缩功能(酌情使用)这次二次开发发现C#对DirectShow的相关信息太少,这次做完也不敢藏私共享出来,还望大家指正

8个专业技巧深度解析FlexibleAdapter:构建高效Android列表的终极指南

FlexibleAdapter是一款专为Android RecyclerView设计的全能适配器库,它将多种高级功能整合到一个库中,显著提升复杂列表的开发效率和用户体验。本文面向中级Android开发者,深入解析FlexibleAdapter的核心机制,提供实战技巧,帮助您避免常见陷阱,构建高性能、可维护的列表界面。通过掌握数据驱动更新、多类型布局、展开折叠、LiveData集成等关键技术,您将能

gitblog_00005的博客 665

假人有限元模型

假人模型,车辆碰撞假人有限元模型,适合做乘员安全的研究者利用

android-advancedrecyclerview 版本演进全解析:从 v0.5 到 v1.0 的破坏性变更、新特性与迁移要点

本篇技术指南以仓库根目录的 [RELEASE-NOTES.md](https://link.gitcode.com/i/818027d416b034529d43f14e13deff39) 为核心骨架,完整梳理 android-advancedrecyclerview(一个提供拖拽排序、侧滑删除、可展开分组等高级能力的 RecyclerView 扩展库)从 v0.5.0 初始发布到 v1.0.0 A

gitblog_00095的博客 402

数学建模模型总结

这是本人在两年内准备参加数学建模竞赛搜集到的模型资料,已经经过了本人的筛选和整理,希望能够对准备参加数学建模竞赛的学弟学妹们提供一些帮助!

Outlook Express 6 (OE6) for Win7/Win8/Win10

英文版 Outlook Express6.0, 兼容Win7/Win10/WinXP,解压就可用。

Android RecycleView notifyItemChanged()刷新闪烁问题处理

在RecycleView notifyItemChanged(position) 刷新得时候部分情况下会出现图片闪烁问题,导致此问题出现的原因有几种,项目中出现了这个问题再次记录下集中解决思路供大家梳理 原因: 1.条件情况下执行了动画操作导致了刷新闪烁问题 2.图片重新加载导致了刷新问题 3:全局刷新导致Item数据重新填充刷新了Item 解决方案: 1.关闭动画效果 //关闭动画效果 SimpleItemAnimator sa=(SimpleItemAnimator )recycle...

馒头 8914

Android的RV列表刷新?Payload 与 Diff 的方式有什么异同?

RecyclerView是我们常用的列表控件,一般来说当Item的数据改变的时候我们需要刷新当前的Item。如何刷新 RV 的列表?基本上有这几种方式:一般来说一个 item 是由多个控件组成的,如 Button、CheckBox、TextView、ImageView、ViewGroup 等组合。当我们点击item的某个控件时,RV 需要重新计算布局、刷新视图来响应交互。

Eqiqi的博客 897

RecycleVIew 调用 notifyItemChanged 那些坑

问题1:最近在项目中遇到一个 物理键盘焦点异常 的问题,每次切换item的时候,焦点总会跳到第一个item的位置,看来看去,原来是这个界面使用了 RecycleView 的问题。在更新数据的时候,调用了 RecyclerViewAdapter.notifyDataSetChanged(),更新了所有item。 解决方法:只更新被选中的item ,调用 RecyclerViewAdapter.n...

Ghost_tal的博客 1万+

RecyclerView的局部刷新(notifyItemChanged(int position,Object payload))

局部刷新的方便之处 RecyclerView的刷新可以分为列表重新加载刷新、item刷新、item中局部刷新。对于前两种的刷新,都会是的列表刷新的时候闪烁一下,而后者则看不出列表有任何闪烁,并且,局部刷新能在一定程度上减少不必要的UI绘制渲染。 RecyclerView 数据刷新的几种方式,RecyclerView 真正的布局刷新的正确方式 notifyDataSetChanged() 刷新...

L0123456L的博客 6718

详解 RecyclerView 中的局部刷新机制 | 开发者说·DTalk

本文原作者: BennuC,原文发布于: BennuCTech前言使用 RecyclerView 的时候会遇到这样一个场景,使用 notifyItemChanged 刷新数据的时候会出现重影或者闪烁的现象。这个问题很容易出现,当我们的列表中有进度显示 (比如下载),这时候需要不停地更新进度,就需要使用 notifyItemChanged。使用 notifyItemChanged 可以只刷新那一个 ...

Android开发者 1002

RecyclerView 数据更新方法 notifyItemChanged/notifyItemInsert/notifyIteRemoved

java.lang.IndexOutOfBoundsException: Inconsistency detected. Invalid view holder adapter positionViewHolder{424b7690 position=7 id=-1, oldPos=8,pLpos:8 scrap tmpDetached no parent} at android.support.v7.widget.RecyclerView

hnjzfwy的博客 2128

RecyclerView的notify方法及其payload参数

  列表的数据更新,通常有两种更新事件,一种是item change event,条目改变事件,就是item中有数据变化了;一种是structural change event,结构改变事件,即插入、删除或者移动了一些item。 这些变化在RecycleView.Adapter中就可以单独更新,提高效率,也更方便一点。RecyclerView.Adapter中有多个notify方法,用户可以有...

Smile_Qian的博客 4204

Android开发各种奇怪问题记录

Android开发各种奇怪问题记录

“点点”专栏 4443

详细解读RecyclerView的局部刷新机制

前言 这篇文章其实之前就完成了,一直遗忘在角落里了,今天无意翻之前的笔记发现的,大部分内容应该还是有效的。 之前在使用RecyclerView的遇到过一个问题,使用notifyItemChanged刷新数据的时候会出现重影或者闪烁的现象。 这个问题很容易出现,当我们的列表中有进度显示(比如下载),这时候需要不停的更新进度,就需要使用notifyItemChanged 使用notifyItemChanged可以只刷新那一个item,这样就避免了像ListView那样全部刷新 但是如果使用notifyItemC

公众号:BennuCTech 2786
上一篇: Android LayoutInflater 相关笔记
下一篇: 《Android 复杂的列表视图新写法 MultiType》知识点整理
OneDeveloper
博客等级 码龄9年 61粉丝 161原创
评论 8
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值