再说Android RecyclerView局部刷新那个坑
RecyclerView局部刷新大家都遇到过,有时候还说会遇见图片闪烁的问题。
优化之前的效果:
优化之后的效果:
如果想单独更新一个item,我们通常会这样做,代码如下:
mLRecyclerViewAdapter.notifyItemChanged(position);
- 1
这里的position就是那个列表项的索引,调用这个方法可以更新一个Item的UI(当然,你要是直接调用notifyDataSetChanged()方法也可以,但这样会造成其他不需要更新的item也会刷新)。
即便如此,图片闪烁还是出现了,什么原因引起来的呢,这里猜测可以有如下几个原因:
流传甚为广泛的一种说法,imageView的宽高不固定导致的(wrap_content)?
是RecyclerView自带的更新动画效果导致的?
是因为图片加载框架(glide 的 animte)的动画效果导致的?
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局部刷新那个坑的更多相关文章
- Android RecyclerView局部刷新那个坑
关键:public final void notifyItemChanged(int position, Object payload) RecyclerView局部刷新大家都遇到过,有时候还说会遇见 ...
- 安卓易学,爬坑不易—腾讯老司机的RecyclerView局部刷新爬坑之路
前言 安卓开发者都知道,RecyclerView比ListView要灵活的多,但不可否认的里面的坑也同样埋了不少人.下面让我们看看腾讯开发工程师用实例讲解自己踩坑时的解决方案和心路历程. 话说有图有真 ...
- 安卓易学,爬坑不易——腾讯老司机的RecyclerView局部刷新爬坑之路
针对手游的性能优化,腾讯WeTest平台的Cube工具提供了基本所有相关指标的检测,为手游进行最高效和准确的测试服务,不断改善玩家的体验.目前功能还在免费开放中. 点击地址:http://wetest ...
- RecyclerView局部刷新那点事
1.局部刷新的引入 提到RecyclerView,我们首先想到的是ListView,对于ListView的局部刷新,我们之前已经有解决方案,[android:ListView的局部刷新]当时的解决方案 ...
- Android listview局部刷新和模拟应用下载(zhu)
在android开发中,listview是比较常用的一个组件,在listview的数据需要更新的时候,一般会用notifyDataSetChanged()这个函数,但是它会更新listview中所有可 ...
- 转:android listview局部刷新和模拟应用下载
在 android开发中,listview是比较常用的一个组件,在listview的数据需要更新的时候,一般会用 notifyDataSetChanged()这个函数,但是它会更新listview中所 ...
- RecyclerView 局部刷新(获取viewHolder 去刷新)
RecyclerView.ViewHolder viewHolder = mRecyclerView.findViewHolderForAdapterPosition(i); if (viewHold ...
- RecyclerView 数据刷新的几种方式 局部刷新 notify MD
Markdown版本笔记 我的GitHub首页 我的博客 我的微信 我的邮箱 MyAndroidBlogs baiqiantao baiqiantao bqt20094 baiqiantao@sina ...
- android:ListView的局部刷新
1.简介 对于android中的ListView刷新机制,大多数的程序员都是很熟悉的,修改或者添加adapter中的数据源之后,然后调用notifyDataSetChanged()刷新ListView ...
随机推荐
- oracle v$sqlarea 分析SQL语句使用资源情况 确认是否绑定变量
-如何确定系统中是否存在绑定变量的情况:首先创建一个表,用于存放整理过得数据:create table t1 as select sql_text from v$sqlarea;----V$SQLAR ...
- log4j.xml写入数据库,只有SQL和参数,无其他信息
<?xml version="1.0" encoding="UTF-8" ?><!DOCTYPE log4j:configuration SY ...
- CXF实战之拦截器Interceptor(四)
拦截器(Interceptor)是CXF功能最基本的扩展点,能够在不正确核心模块进行改动的情况下.动态加入非常多功能.拦截器和JAX-WS Handler.Filter的功能相似,当服务被调用时.就会 ...
- iOS开发技巧 - 使用Alerts和Action Sheets显示弹出框
解决方案: (Swift) 使用UIAlertController类 (Objective-C) 使用UIAlertView类 代码: (Swift) import UIKit class ViewC ...
- 树莓派中GPIO针角定义图
一.上图 二.上图
- C#和网页js互调代码
C#和网页js互调代码 1.先写个网页放在主程序目录下:test.html <!DOCTYPE html> <html lang="en" xmlns=" ...
- JavaScript正则式练习
使用正则式匹配第一个数字和最后一个数字,使用环视 str2 = 09051 : Fast Food Restaurants - Concession Stands/Snack Bars Delicat ...
- C# •MouseDown •MouseDown •MouseUp 的先后顺序
鼠标按下事件发生的顺序 MouseDown event. Click event. MouseDownevent. MouseUp event. 可以写个测试,放一个picture控件 private ...
- llvm code call graph
https://www.ics.usi.ch/images/stories/ICS/slides/llvm-graphs.pdf
- ReactNative踩坑日志——函数绑定this
ES6语法定义的函数没有自动绑定this,所以在函数中使用了 this.xxx 就会报错,因为没有把类实例等this传进函数中. 有两种方法绑定this: 法1:在构造函数中为其他函数绑定this c ...