Java Android在RecyclerView上抛出动作
我最近在安卓5+上玩了一点RecyclerView和ViewHolder的概念。适配器实现处理相当大的数据集(即约60000项),在调用onBindViewHolder(…)时从internet请求。网络请求由volley库处理,响应表示用于填充视图持有者的数据模型 现在,当快速投掷(即以一定速度移动,不同于用户触摸设备并在屏幕上缓慢移动的滑动)时,适配器中的所有位置都会调用onBindViewHolder,这不是一件好事,因为动画速度太快,大多数ViewHolder都看不见。例如,如果用户在几秒钟内从位置5滑动到300,大多数视图都无法读取,但会调用bind方法。由于适配器从网络获取数据模型,因此发出了很多请求,其中大多数都没有用处,而孔处理只是将请求的处理延迟到位置300左右,这是用户可以真正观察到的位置 如何处理仅要求可见位置的问题? 我的第一种方法是对截取处理队列中的请求进行优先级排序。这并没有解决很多问题,因为每个网络请求都是以不同的顺序处理的。我的第二种方法是在添加新请求时取消所有现有请求。它对我来说不是很好,从设计的角度来看,我不喜欢这个解决方案Java Android在RecyclerView上抛出动作,java,android,adapter,android-volley,android-viewholder,Java,Android,Adapter,Android Volley,Android Viewholder,我最近在安卓5+上玩了一点RecyclerView和ViewHolder的概念。适配器实现处理相当大的数据集(即约60000项),在调用onBindViewHolder(…)时从internet请求。网络请求由volley库处理,响应表示用于填充视图持有者的数据模型 现在,当快速投掷(即以一定速度移动,不同于用户触摸设备并在屏幕上缓慢移动的滑动)时,适配器中的所有位置都会调用onBindViewHolder,这不是一件好事,因为动画速度太快,大多数ViewHolder都看不见。例如,如果用户在几
我真正的问题是,您将如何处理此问题?是的,我已通过保持每个适配器位置的状态来解决我的问题。RecyclerView.Adapter有两种方法,分别是当用户即将看到视图或当视图被移除时,发出信号通知视图附加到窗口(VH保持架)和
打开视图从窗口分离(VH保持架)
我创建了一个简单的singleton类来保持每个适配器位置的状态:
import java.util.HashSet;
import java.util.Set;
/**
* Created by fauri on 14/06/2015.
*/
public class ViewHolderState {
private static final ViewHolderState ourInstance = new ViewHolderState();
private Set<Integer> recycled = new HashSet<>();
private ViewHolderState() {
}
public static ViewHolderState getInstance() {
return ourInstance;
}
public void addRecycledView(int position) {
recycled.add(position);
}
public void removeRecycledView(int position) {
recycled.remove(position);
}
public boolean isViewRecycled(int position) {
return recycled.contains(position);
}
public void clearAll() {
recycled.clear();
}
}
这只是为了保持每个适配器位置的状态。现在,在触发网络调用的业务逻辑中,您只需获取singleton实例并检查isViewRecycled(int adapterPosition)
。如果视图被回收,则无需进行网络呼叫
当然,这是一个简单的解决方案。可以通过添加线程安全性(即使用Collection.synchronizedSet(…)或使方法同步化)或仅使用另一种模式来改进代码。Java大师们并不真正喜欢单例模式
总之,总的想法是利用视图上的
附件到窗口
和视图上的从窗口分离
您对此有什么结论吗?我在使用Volley的NetworkImageView时也遇到同样的问题。
private ViewHolderState viewHolderState = ViewHolderState.getInstance();
@Override
public void onViewDetachedFromWindow(CardViewHolder holder) {
super.onViewDetachedFromWindow(holder);
viewHolderState.addRecycledView(holder.getAdapterPosition());
}
@Override
public void onViewAttachedToWindow(CardViewHolder holder) {
super.onViewAttachedToWindow(holder);
viewHolderState.removeRecycledView(holder.getAdapterPosition());
}