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

优化之前的效果:

优化之后的效果:

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

mLRecyclerViewAdapter.notifyItemChanged(position);
  • 1

这里的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
  • 1

翻译过来就是如果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 >= 0) {
//得到要更新的item的view
View view = mRecyclerView.getChildAt(position - firstItemPosition + 1);
if (null != mRecyclerView.getChildViewHolder(view)) {
ProductsViewHolder viewHolder = (ProductsViewHolder) mRecyclerView.getChildViewHolder(view); //do something } } }

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

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

  1. Android RecyclerView局部刷新那个坑

    关键:public final void notifyItemChanged(int position, Object payload) RecyclerView局部刷新大家都遇到过,有时候还说会遇见 ...

  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. Reshaper cannot resolve symbol

    问题 不知道出了什么问题,在代码视图发现有些关键词显示为红色,并且Reshaper提示消息为Reshaper cannot resolve symbol XXX ,但编辑不会报错. 虽然不影响使用,但 ...

  2. 【树莓派】树莓派刷Android系统

    树莓派3安装Android TV系统图文教程 http://www.mz6.net/news/android/6866.html 树莓派3 Android TV系统怎样安装?树莓派3一个重要用途就是当 ...

  3. 微信小程序 - 3d轮播图组件(基础)

    <!-- 目前仅支持data数据源来自banner,请看测试案例 ################ 以上三种形式轮播: 1. basic 2. 3d 3. book basic即普通轮播 3d即 ...

  4. 开发JAVA9以上的项目时,出现ClassNotFoundException: javax.xml.bind.JAXBException的解决方法

    一.问题描述: 开发JAVA9以上的项目时,出现ClassNotFoundException: javax.xml.bind.JAXBException的解决方法 二.问题样例 三.解决方案 打开mv ...

  5. MACD判断定背离,底背离

    MACD背离: 价格创新高而指标却下跌 价格创新低而指标却上涨 缠中说禅背离 多次缠绕中唇吻的面积更小 看图说话:

  6. storm中worker、executor、task之间的关系

    这里做一些补充: worker是一个进程,由supervisor启动,并只负责处理一个topology,所以不会同时处理多个topology. executor是一个线程,由worker启动,是运行t ...

  7. Kinect2.0获取关节姿态(Joint Orientation)

    Bones Hierarchy 骨骼层次结构从SpineBase作为根节点开始,一直延伸到肢体末端(头.指尖.脚): 层级结构如下图所示: 通过IBody::GetJointOrientations函 ...

  8. V-rep学习笔记:机器人模型创建3—搭建动力学模型

    接着之前写的V-rep学习笔记:机器人模型创建2—添加关节继续机器人创建流程.如果已经添加好关节,那么就可以进入流程的最后一步:搭建层次结构模型和模型定义(build the model hierar ...

  9. SpringBoot之配置google kaptcha

    项目中引入POM: <dependency> <groupId>com.google.code.kaptcha</groupId> <artifactId&g ...

  10. python模块之importlib(py3中功能有明显加强)

    # -*- coding: utf-8 -*-#python 27#xiaodeng#python模块之importlib(py3中功能有明显加强)