关键:public final void notifyItemChanged(int position, Object payload)

RecyclerView局部刷新大家都遇到过,有时候还说会遇见图片闪烁的问题。

优化之前的效果:

优化之后的效果:

如果想单独更新一个item,我们通常会这样做,代码如下:

mLRecyclerViewAdapter.notifyItemChanged(position);

这里的position就是那个列表项的索引,调用这个方法可以更新一个Item的UI(当然,你要是直接调用notifyDataSetChanged()方法也可以,但这样会造成其他不需要更新的item也会刷新)。

即便如此,图片闪烁还是出现了,什么原因引起来的呢,这里猜测可以有如下几个原因:

  1. 流传甚为广泛的一种说法,imageView的宽高不固定导致的(wrap_content)?

  2. 是RecyclerView自带的更新动画效果导致的?

  3. 是因为图片加载框架(glide 的 animte)的动画效果导致的?

  4. getView中(RecyclerView中是onBindViewHolder)加载图片的时候,设置一个tag,当发现这个imageView的tag和之前的tag一致时就不加载。

这里我们不再对上面的原因进行具体的分析,针对上面可能引起闪烁的原因进行一一验证后的结果是令人感到失望的:都不是引起图片闪烁的根本原因。

那么怎么解决这个图片闪烁的问题呢?通过查看api,我们发现了另一个方法:

重点看payload参数介绍:

payload Optional parameter, use null to identify a "full" update

翻译过来就是如果payload参数是null,那么就会来一个“完整的”更新,也就是说会全部更新。

我们再看一下mLRecyclerViewAdapter.notifyItemChanged(position)的源码:

从源码中看到,notifyItemChanged(position)调用了 notifyItemRangeChanged(int positionStart, int itemCount)方法,源码如下:

notifyItemRangeChanged(int positionStart, int itemCount)方法最终还是调用了notifyItemRangeChanged(int positionStart, int itemCount, Object payload)方法,只是payload参数是null。

那么如果payload传一个不为null的参数,就可以实现对列表项中的具体控件更新了吗?我们通过代码验证下。

模拟更新一条数据:

这里,我们将payload参数赋值为”jdsjlzx”,当然你也可以赋值为其他值,只要不空就行。

重写adapter中的onBindViewHolder(RecyclerView.ViewHolder holder, int position, List payloads)方法:

如果payloads列表不是空的,如上图所示,你就可以在else代码块里面刷新你想更新的控件了(记得不需要更新的控件就不要写在这里了)。

注意:

以上代码都是结合LRecyclerView框架来测试的,想要体验完整demo,请参考:https://github.com/jdsjlzx/LRecyclerView

总结

由此看来,RecyclerView做局部刷新还是非常容易的,其实就是使用好带payload参数的这个notifyItemChanged方法,以及重写带payload的这个onBindViewHolder方法,在onBindViewHolder中去刷新你想更新的控件即可。

PS:

拿朋友圈来说,我发一张照片,这就是一个item,但这个item里还要加上赞和评论。 
当我有评论和赞要刷新时,我需要判断当前要改动的item是否是屏幕中的可见位置。如果是,通过调用带payload参数的这个notifyItemChanged方法更新item,就能达到只刷赞或者只刷评论,而不用重新加载照片(也就是图片闪烁的原因)的效果。

怎么判断当前position是位于屏幕中呢?下面给出参考代码:

private void doAnim(int position) {
int firstItemPosition = layoutManager.findFirstVisibleItemPosition();
if (position - firstItemPosition >= ) {
//得到要更新的item的view
View view = mRecyclerView.getChildAt(position - firstItemPosition + );
if (null != mRecyclerView.getChildViewHolder(view)) {
ProductsViewHolder viewHolder = (ProductsViewHolder) mRecyclerView.getChildViewHolder(view); //do something } } }

上面代码同时也获取到了ViewHolder视图,有了ViewHolder,你还可以做其他操作哦(比如item动画效果)。

Android RecyclerView局部刷新那个坑的更多相关文章

  1. 再说Android RecyclerView局部刷新那个坑

      RecyclerView局部刷新大家都遇到过,有时候还说会遇见图片闪烁的问题. 优化之前的效果: 优化之后的效果: 如果想单独更新一个item,我们通常会这样做,代码如下: mLRecyclerV ...

  2. 安卓易学,爬坑不易—腾讯老司机的RecyclerView局部刷新爬坑之路

    前言 安卓开发者都知道,RecyclerView比ListView要灵活的多,但不可否认的里面的坑也同样埋了不少人.下面让我们看看腾讯开发工程师用实例讲解自己踩坑时的解决方案和心路历程. 话说有图有真 ...

  3. 安卓易学,爬坑不易——腾讯老司机的RecyclerView局部刷新爬坑之路

    针对手游的性能优化,腾讯WeTest平台的Cube工具提供了基本所有相关指标的检测,为手游进行最高效和准确的测试服务,不断改善玩家的体验.目前功能还在免费开放中. 点击地址:http://wetest ...

  4. RecyclerView局部刷新那点事

    1.局部刷新的引入 提到RecyclerView,我们首先想到的是ListView,对于ListView的局部刷新,我们之前已经有解决方案,[android:ListView的局部刷新]当时的解决方案 ...

  5. Android listview局部刷新和模拟应用下载(zhu)

    在android开发中,listview是比较常用的一个组件,在listview的数据需要更新的时候,一般会用notifyDataSetChanged()这个函数,但是它会更新listview中所有可 ...

  6. 转:android listview局部刷新和模拟应用下载

    在 android开发中,listview是比较常用的一个组件,在listview的数据需要更新的时候,一般会用 notifyDataSetChanged()这个函数,但是它会更新listview中所 ...

  7. RecyclerView 局部刷新(获取viewHolder 去刷新)

    RecyclerView.ViewHolder viewHolder = mRecyclerView.findViewHolderForAdapterPosition(i); if (viewHold ...

  8. RecyclerView 数据刷新的几种方式 局部刷新 notify MD

    Markdown版本笔记 我的GitHub首页 我的博客 我的微信 我的邮箱 MyAndroidBlogs baiqiantao baiqiantao bqt20094 baiqiantao@sina ...

  9. android:ListView的局部刷新

    1.简介 对于android中的ListView刷新机制,大多数的程序员都是很熟悉的,修改或者添加adapter中的数据源之后,然后调用notifyDataSetChanged()刷新ListView ...

随机推荐

  1. JSP的会话(Session)跟踪

    以下内容引用自http://wiki.jikexueyuan.com/project/jsp/session-tracking.html: 会话(Session) HTTP是一个“无状态”协议,这意味 ...

  2. DTRACE简介(1)

    https://blogs.oracle.com/swan/entry/dtrace%E7%AE%80%E4%BB%8B By samwan on 三月 20, 2007 记得几年前看过一部美国大片叫 ...

  3. MySQL入门笔记 - 数据库概述

    参考书籍<MySQL入门很简单> 1.数据库 数据库(DataBase)是一个存储数据的仓库,将数据按照特定的规律存储在磁盘上. 2.数据存储方式 数据存储方式分为3个阶段:人工管理阶段. ...

  4. SAS学习笔记 - 基本原理与概念

    1.赋值符号 由一个尖括号和一个符号组成,可以从左到右也可以从右到左,即“->”或者“<-”. 赋值号也可以使用等号“=”. 如果对象已经存在,那么原先的值会被覆盖.除了可以赋一个数值,还 ...

  5. dubbo安装和使用

    转载:http://blog.csdn.net/zjcjava/article/details/78766095 背景 Dubbo的开源人梁飞在内部的交流会上宣布重启dubbo的维护和更新,具体PPT ...

  6. 网易互娱2017实习生招聘游戏研发工程师在线笔试第二场 C

    偶尔碰到这题,简单数位DP题,然而我已生疏了…… 这次算是重新想到的,看来对DP的理解有增进了…… dp[i][j][k],表示前i为,mod为j,是否出现2.3.5的剩下的数位可组成的数字.答案就是 ...

  7. linux系统的开机流程

    开机流程: 1)BIOS:开机主动运行的韧体.会认识第一个可开机设备. 2)MBR:第一个可开机设备的第一个扇区内的主引导分区块.当中包括引导载入程序. 3)引导载入程序:一支可读取内核文件来运行的软 ...

  8. 2016/2/19 css样式表 Cascading Style Sheet 叠层样式表 美化HTML网页

    一.样式表 (一)样式表的分类 1.内联样式表 和HTML联合显示,控制精确,但是可重用性差,冗余较多. 例:<p style="font-size:14px;">内联 ...

  9. iOS开发——基础篇——get和post请求的区别

    HTTP 定义了与服务器交互的不同方法,最常用的有4种,Get.Post.Put.Delete,如果我换一下顺序就好记了,Put(增),Delete(删),Post(改),Get(查),即增删改查,下 ...

  10. 记一次ORA-600[13011]

    SunOS 5.10 Oracle 10.2.0.2.0 开发环境某一数据库出现ora-600报错. alert.log中的报错信息: Thu Nov 13 15:11:43 2014 Errors ...