如何实现支持折叠/展开切换展示条目的Android RecyclerView
RecyclerView 折叠功能实现方案
核心思路是将折叠逻辑内聚到Adapter内部,不拆分原始数据源,用局部刷新代替全量刷新,实现更简洁高效。
具体实现步骤
1. 内部变量与基础配置
Adapter内部直接持有全量数据源,新增展开状态标记、预览条数常量,同时将底部操作按钮作为单独的Item类型处理,和普通数据条目逻辑隔离:
class FoldableListAdapter( // 仅初始化时传入一次全量数据即可,后续无需切换数据源 private val fullData: List<YourDataBean> ) : RecyclerView.Adapter<RecyclerView.ViewHolder>() { // Item类型区分 private val TYPE_DATA = 0 private val TYPE_FOOTER = 1 // 预览状态展示的条目数 private val PREVIEW_COUNT = 2 // 展开状态标记,默认收起 private var isExpanded = false
2. 重写条目计数与类型判断
根据展开状态动态计算实际展示的条目数量,数据源总条数小于等于2时可以直接隐藏底部按钮:
override fun getItemCount(): Int { // 数据总量小于等于预览数,直接展示全部数据,不需要底部按钮 if (fullData.size <= PREVIEW_COUNT) return fullData.size // 否则计算展示的数据条数+1个底部按钮 val showDataCount = if (isExpanded) fullData.size else PREVIEW_COUNT return showDataCount + 1 } override fun getItemViewType(position: Int): Int { return if (position == itemCount - 1 && fullData.size > PREVIEW_COUNT) { TYPE_FOOTER } else { TYPE_DATA } }
3. 绑定逻辑与状态切换
条目绑定正常处理,底部按钮点击时切换状态,用局部刷新API完成列表更新,自带条目增删动画:
override fun onBindViewHolder(holder: RecyclerView.ViewHolder, position: Int) { when (getItemViewType(position)) { TYPE_DATA -> { (holder as DataViewHolder).bind(fullData[position]) } TYPE_FOOTER -> { val footerHolder = holder as FooterViewHolder footerHolder.operateBtn.text = if (isExpanded) "隐藏" else "查看全部" footerHolder.operateBtn.setOnClickListener { toggleExpand() } } } } private fun toggleExpand() { val oldShowCount = if (isExpanded) fullData.size else PREVIEW_COUNT isExpanded = !isExpanded val newShowCount = if (isExpanded) fullData.size else PREVIEW_COUNT val diffCount = newShowCount - oldShowCount // 局部刷新代替全量notifyDataSetChanged if (diffCount > 0) { notifyItemRangeInserted(PREVIEW_COUNT, diffCount) } else { notifyItemRangeRemoved(PREVIEW_COUNT, -diffCount) } // 刷新底部按钮文字 notifyItemChanged(itemCount - 1) } // 两种ViewHolder的定义、创建逻辑此处省略,按常规RecyclerView写法实现即可 }
方案优势
- 逻辑完全内聚在Adapter内部,外部无需处理状态、无需切换传入的数据源,仅需初始化时传入全量列表即可
- 用
notifyItemRangeInserted/notifyItemRangeRemoved做局部刷新,性能比全量刷新高,还自带系统默认的条目增删动画 - 没有多余的嵌套逻辑,完全匹配仅需两种展示状态的需求,后续要修改预览条数仅需修改
PREVIEW_COUNT常量即可 - 自动适配数据量小于等于预览数的场景,不会多余展示底部操作按钮
内容的提问来源于stack exchange,提问作者testivanivan
相关产品推荐
相关产品推荐

