【前言】
一般而言,要是RecyclerView.Adapter
的getItemViewType
方法返回相同值时,RecyclerView就会复用已经滑出屏幕变为不可见的ViewHolder,假如被复用的ViewHolder持有的View没有被重新赋值或者恢复原始状态,就会出现显示被复用之前的View状态的这种现象,我们可以认为出现RecyclerView ViewHolder复用出现错乱
【复用错乱解决方案】
1)方案一:直接在RecyclerView.Adapter的onBindViewHolder
方法里设置:
holder.setIsRecyclable(false);
加了这个设置,不管getItemViewType是否返回相同值,一概都不复用ViewHolder,网上一搜基本都是说这种方案,这个方案是挺简洁,但是也很致命,因为这样在滑动过程中会不断创建新的对象,要是RecyclerView的item图片比较多,那么很容易就会出现OOM内存溢出
2)方案二:在onBindViewHolder
方法里面对ViewHolder持有的所有view都按需重新赋值或者恢复初始状态
,比如:
- TextView、ImageView该重新赋值就重新赋值,要是异步请求,可以先赋默认值,设置默认图片
- 该隐藏的布局或者设置宽高的,也按传进来的对象值设置好,总之不要漏掉没有设置的View或者宽高、可见性属性,就不会出现错乱问题
推荐用第二种方案处理,这种才是治标又治本的方法
【备注】
当 RecyclerView 的条目很少的时候,比如只有6个,将 RecyclerView 从上滑动到下,这个时候是正常的,onBindViewHolder 会调用,不过此时从底部上滑的时候,上方的 item 从不可见到可见的这个过程中,onBindViewHolder 并没有调用,这个时候我也就没办法进行一些刷新 item 的操作了。
这个问题的原因是 onBindViewHolder 方法不调用导致的, StackOverflow的解决方案:
你可以调用
recyclerView.setItemViewCacheSize(int);