目前正在做一个文件下载的功能,现在在 RecyclerView 条目中的 Progressbar 刷新问题上卡住了。项目中是通过观察者模式来监听文件下载的状态,通过回调观察者对象中的 updateProgress(FileInfo fileinfo)方法(回调频率为 50ms)来实现 RecyclerView 中 item 的状态更新。
目前做了一下几种尝试:
每次回调 updateProgress(FileInfo fileinfo)通过获取 FileInfo 对象所在 RecyclerView 的 position 位置,对单个 item 进行刷新。虽然可以实现功能,但是由于刷新频率太高,会造成界面卡顿。
每次回调 updateProgress(FileInfo fileinfo)时 通过调用 notifyDataChanged()方法来对整个 RecyclerView 进行刷新。同样由于更新频率太高滑动起来会感受到明显的卡顿。
在 ViewHolder 中注册观察者,然后直接在 ViewHolder 中对 item 中的 View 进行刷新。滑动起来的体验最好,但是由于我太菜,对 RecyclerView 的复用机制了解的不深入。目前还想不到合适的逻辑来解决复用导致的显示错乱的问题。
希望各位大佬给小弟提点建议。
1
maninfog 2018-10-21 12:50:03 +08:00 via iPhone 1
1.增大刷新时间… 50ms 也就是 20 个刷新才 1s ??你设置成 200ms 肉眼根本感受不出来差别好么
2.搜索 recyclerview payload 可以实现局部中的局部刷新 |
2
HarryQu 2018-10-21 13:02:34 +08:00
刷新时间设置成 500ms 或者 1s ,体验上都不会太差的。
|
3
HarryQu 2018-10-21 13:12:14 +08:00
1. 我之前做这种功能, 项目中做了专门的下载模块 ,下载任务直接丢给下载模块。页面刷新通过 EventBus 来解耦。
例如 EventBus 将需要更新任务的 url 、进度之类的传递过来 , RecyclerView 根据 url 之类的拿到 item 位置 , 然后刷新指定位置的数据。 2. 你要注意下载刷新间隔问题 , 单个任务 50ms , 如果同时下载多个任务 , 你这个页面会非常卡顿的。因此下载进度刷新间隔为 500 ms 或者 1s。 |
4
wsxyeah 2018-10-21 13:33:24 +08:00
|
5
GoodRainChen 2018-10-22 10:13:29 +08:00 1
"然后直接在 ViewHolder 中对 item 中的 View 进行刷新"
不说别的,这个方案就可行啊 每次 bindView 的时候把 position 更新在 ViewHolder 里,根据 position 选择性监听回调就可以了 |
6
xiaohei233 2018-10-22 11:06:07 +08:00
RecyclerView 频繁刷新的时候再快速滑动,会崩溃。我之前遇到是这样的问题,还是控制刷新频率吧。
|
7
BryanYue 2018-10-22 13:53:25 +08:00
第三点 可以用 Map 缓存对应进度数据,key 就是 position 或者 List 的 position
不要频繁刷新,可以比较 进度跟之前进度有 1%(可自己定义)差别是 在刷新 UI 刷新方案推荐第一种 局部刷新方案 DiffUtil 可以了解下 ,直接比较旧数据 自动刷新 UI,系统封装好了 |
8
merpyzf OP @maninfog 谢谢,问题已经解决,50ms 的刷新频率确实没什么意义,唯一的意义就是能够带来一丝丝感官上的快感。已修改成 200ms 刷新一次。
|
10
merpyzf OP @GoodRainChen 谢谢,之前就是采用这种方式来刷新的,由于逻辑没控制好导致数据错乱。昨天用了些时间把逻辑理清并解决了数据错乱的问题,使用这种方式真的可以很好的解决这种刷新频率过高的需求,并且滑动的过程中根本不会出现任何卡顿。
|