RecyclerView notifyItem闪烁的问题
2016-06-22 09:08
357 查看
之前我们做点赞,用listview做的话,就是在item实现点击后,写一个scal动画,不过现在都转到RecyclerView,那么要做这种效果于是做了一个notifyItemChanged()的操作,功能都顺利实现,美中不足的是当前Item闪了一下,QA甚至为此提了Bug,一开始以为是图片加载库的问题,之后随着图片加载库从ImageLoader换成Picaso,又换成Glide,这个Bug一直如影随形。后来才发现“闪一下”原来是RecyclerView的默认动画,我的代码里有这样一句
![](//upload-images.jianshu.io/upload_images/1187237-31bf87528b978946.gif?imageMogr2/auto-orient/strip)
before.gif
先来了解下这个RecyclerView的动画吧。
RecyclerView.ItemAnimator
ItemAnimator能够帮助Item实现独立的动画。
ItemAnimator触发于以下三种事件:
某条数据被插入到数据集合中
从数据集合中移除某条数据
更改数据集合中的某条数据
在Android中默认实现了一个DefaultItemAnimator
,我们可以通过以下代码为Item增加动画效果:
在之前的版本中,当数据集合发生改变时,我们通过调用
向指定位置插入Item
移除指定位置Item
更新指定位置Item
但是现在的问题就是,调用notifyItem*()方法会触发RecyclerView的默认动画,而这个动画我并不想要,但是似乎并没有合适的办法来屏蔽这个动画,QA甚至认为这是个Bug,需要修复。与同行们交流了下,也有人遇到同样的问题,解决办法居然是调用notifyDataSetChanged()方法来刷新数据,这样就不会有闪一下的动画了。但是这样不就失去使用RecyclerView的优势和意义了吗?
最后我是通过重写RecyclerView的动画来解决这一“Bug”。
将DefaultItemAnimator类里的代码全部copy到自己写的动画类中,然后做一些修改。
首先找到
找到方法里这两句代码:
1:
2:
替换成:
1:
2
也就是说分别去掉上述代码中的
mRecyclerView.setItemAnimator(new DefaultItemAnimator());原来是这句代码搞的鬼,于是注掉再跑,但并没什么卵用。于是又改成
mRecyclerView.setItemAnimator(null);仍然没什么卵用。看来加不加这句,RecyclerView都默认执行了这个动画,看来还有点小麻烦。
![](http://upload-images.jianshu.io/upload_images/1187237-31bf87528b978946.gif?imageMogr2/auto-orient/strip)
before.gif
先来了解下这个RecyclerView的动画吧。
RecyclerView.ItemAnimator
ItemAnimator能够帮助Item实现独立的动画。
ItemAnimator触发于以下三种事件:
某条数据被插入到数据集合中
从数据集合中移除某条数据
更改数据集合中的某条数据
在Android中默认实现了一个DefaultItemAnimator
,我们可以通过以下代码为Item增加动画效果:
recyclerView.setItemAnimator(new DefaultItemAnimator());
在之前的版本中,当数据集合发生改变时,我们通过调用
notifyDataSetChanged()来刷新列表,因为这样做会触发列表的重绘,所以并不会出现任何动画效果,但现在我的需求是只改变了当前一个Item的状态,因此需要调用一些以
notifyItem*()作为前缀的特殊方法,比如:
向指定位置插入Item
public final void notifyItemInserted(int position)
移除指定位置Item
public final void notifyItemRemoved(int position)
更新指定位置Item
public final void notifyItemChanged(int position)
但是现在的问题就是,调用notifyItem*()方法会触发RecyclerView的默认动画,而这个动画我并不想要,但是似乎并没有合适的办法来屏蔽这个动画,QA甚至认为这是个Bug,需要修复。与同行们交流了下,也有人遇到同样的问题,解决办法居然是调用notifyDataSetChanged()方法来刷新数据,这样就不会有闪一下的动画了。但是这样不就失去使用RecyclerView的优势和意义了吗?
最后我是通过重写RecyclerView的动画来解决这一“Bug”。
public class NoAlphaItemAnimator extends RecyclerView.ItemAnimator { }
将DefaultItemAnimator类里的代码全部copy到自己写的动画类中,然后做一些修改。
首先找到
private void animateChangeImpl(final ChangeInfo changeInfo) {}方法。
找到方法里这两句代码:
1:
oldViewAnim.alpha(0).setListener(new VpaListenerAdapter() { ... }
2:
newViewAnimation.translationX(0).translationY(0).setDuration(getChangeDuration()).alpha(1).setListener(new VpaListenerAdapter() { ... }
替换成:
1:
oldViewAnim.setListener(new VpaListenerAdapter() { ... }
2
newViewAnimation.translationX(0).translationY(0).setDuration(getChangeDuration()).setListener(new VpaListenerAdapter() { ... }
也就是说分别去掉上述代码中的
alpha(0)和
alpha(1),然后保存。这个时候基本就打工告成了。最后在自己的RecyclerView中进行如下调用
mRecyclerView.setItemAnimator(new NoAlphaItemAnimator());,再跑起来,bug完美解决。
相关文章推荐
- RecyclerView notifyItem闪烁的问题
- RecyclerView notifyItem闪烁的问题
- Alpha阶段项目总结
- 首师大附中互测题:LJX的校园:入学典礼【C003】
- 一次DB2数据库连接失败(SQLSTATE=08001)的解决方法
- action
- CocoPod 安装使用
- VII Python(6)基础知识(re正则表达式、MySQLdb模块)
- Android Studio开发NDK流程--经验
- How to integrate Identity System in Activiti
- oracle imp导入库到指定表空间
- 协方差矩阵的一些理解,转载
- LDPC 学习记录
- Nginx端口的修改
- Linux打印出netstat -anp 里的Send_Q发送堵的TCP连接
- 提高mysql千万级大数据SQL查询优化30条经验(Mysql索引优化注意)
- 6.22软件工程总结
- C# 中正则表达式 Group 分组【转】
- android面试日记--20160619
- java程序性能优化