RecyclerView更换所有条目ViewHolder时清除缓存无效问题咨询
RecyclerView全局更换ViewHolder布局操作指南
为什么recyclerView.recycledViewPool.clear()不生效
RecyclerView的缓存共分为4层,recycledViewPool属于最底层的复用缓存,你调用清除方法时:
- 屏幕上正在显示的条目会被存放在
mAttachedScrap缓存区 - 离屏最近的默认2条条目会被存放在
mCachedViews缓存区
上述两个区域的缓存不受recycledViewPool.clear()影响,所以RecyclerView依然会复用旧的视图。
完整实现方案
前提:改造Adapter适配多布局
你需要先给Adapter新增布局类型标记,让RecyclerView可以区分两种不同的ViewHolder,避免跨布局复用:
// 1. 定义两种布局类型常量 private static final int LAYOUT_OLD = 0; private static final int LAYOUT_NEW = 1; // 2. 新增布局切换标记 private boolean isUseNewLayout = false; // 3. 提供公开的切换方法 public void toggleLayoutType() { isUseNewLayout = !isUseNewLayout; } // 4. 重写getItemViewType返回对应布局类型 @Override public int getItemViewType(int position) { return isUseNewLayout ? LAYOUT_NEW : LAYOUT_OLD; } // 5. onCreateViewHolder中根据viewType加载不同布局 @Override public ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) { LayoutInflater inflater = LayoutInflater.from(parent.getContext()); if (viewType == LAYOUT_OLD) { return new OldViewHolder(inflater.inflate(R.layout.item_old, parent, false)); } else { return new NewViewHolder(inflater.inflate(R.layout.item_new, parent, false)); } } // onBindViewHolder无需修改原有逻辑,依然绑定原有数据即可
点击按钮触发切换的操作
点击按钮时按以下顺序执行,即可完成所有条目(包括当前显示条目)的ViewHolder更换,数据完全不变:
- 第一步:调用Adapter的切换方法更新布局标记
- 第二步:清除RecyclerView所有层级的缓存
- 第三步:通知数据集变更触发视图重建
对应代码示例:
// 触发切换 yourAdapter.toggleLayoutType(); // 全层级清除缓存 recyclerView.recycledViewPool.clear(); int cacheSize = recyclerView.getItemViewCacheSize(); recyclerView.setItemViewCacheSize(0); recyclerView.setItemViewCacheSize(cacheSize); // 通知更新,当前展示的条目也会自动触发重建 yourAdapter.notifyDataSetChanged();
如果你当前只展示1条数据,也可以把最后一步换成yourAdapter.notifyItemChanged(0),性能更好。
内容的提问来源于stack exchange,提问作者Mike U
相关产品推荐
相关产品推荐

