Android Kotlin实现嵌套RecyclerView,父级与子级均带Footer
核心思路
不管是父级还是子级RecyclerView,添加Footer的核心都是通过多类型Item实现——在Adapter中区分普通数据项和Footer项,分别加载对应布局。
步骤1:定义Item类型常量
在Adapter中先明确两种Item类型:
private const val TYPE_ITEM = 0 private const val TYPE_FOOTER = 1
步骤2:实现子级RecyclerView的Adapter
class ChildAdapter(private val dataList: MutableList<Any>) : RecyclerView.Adapter<RecyclerView.ViewHolder>() { override fun getItemViewType(position: Int): Int { return if (position == dataList.size - 1) TYPE_FOOTER else TYPE_ITEM } override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): RecyclerView.ViewHolder { return if (viewType == TYPE_FOOTER) { val footerView = LayoutInflater.from(parent.context).inflate(R.layout.item_footer, parent, false) FooterViewHolder(footerView) } else { val itemView = LayoutInflater.from(parent.context).inflate(R.layout.item_child_data, parent, false) ChildItemViewHolder(itemView) } } override fun onBindViewHolder(holder: RecyclerView.ViewHolder, position: Int) { if (holder is ChildItemViewHolder) { val data = dataList[position] as ChildData holder.tvContent.text = data.content } // Footer无需绑定数据,直接显示即可 } override fun getItemCount(): Int { // 原数据量+1个Footer return dataList.size + 1 } class ChildItemViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) { val tvContent: TextView = itemView.findViewById(R.id.tv_child_content) } class FooterViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) }
步骤3:实现父级RecyclerView的Adapter
逻辑和子级一致,仅数据项布局包含子RecyclerView:
class ParentAdapter(private val parentDataList: MutableList<Any>) : RecyclerView.Adapter<RecyclerView.ViewHolder>() { override fun getItemViewType(position: Int): Int { return if (position == parentDataList.size - 1) TYPE_FOOTER else TYPE_ITEM } override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): RecyclerView.ViewHolder { return if (viewType == TYPE_FOOTER) { val footerView = LayoutInflater.from(parent.context).inflate(R.layout.item_footer, parent, false) FooterViewHolder(footerView) } else { val itemView = LayoutInflater.from(parent.context).inflate(R.layout.item_parent_data, parent, false) ParentItemViewHolder(itemView) } } override fun onBindViewHolder(holder: RecyclerView.ViewHolder, position: Int) { if (holder is ParentItemViewHolder) { val parentData = parentDataList[position] as ParentData holder.tvTitle.text = parentData.title // 初始化子级RecyclerView holder.childRecyclerView.layoutManager = LinearLayoutManager(holder.itemView.context) val childAdapter = ChildAdapter(parentData.childDataList) holder.childRecyclerView.adapter = childAdapter } } override fun getItemCount(): Int { return parentDataList.size + 1 } class ParentItemViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) { val tvTitle: TextView = itemView.findViewById(R.id.tv_parent_title) val childRecyclerView: RecyclerView = itemView.findViewById(R.id.rv_child) } class FooterViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) }
步骤4:准备布局文件
item_child_data.xml:子级普通数据项布局item_parent_data.xml:父级数据项布局(内部包含子RecyclerView)item_footer.xml:通用Footer布局(比如显示“已加载全部”的TextView)
注意事项
- 必须保证
getItemCount()返回值为原数据量+1,否则会出现数组越界 - 父级和子级Footer可复用同一布局,也可根据需求单独定义样式
- 若需动态控制Footer显示/隐藏,可在
getItemCount()中根据条件返回对应数量

内容的提问来源于stack exchange,提问作者Yash Dadhich
相关产品推荐
相关产品推荐

