You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Android Kotlin实现嵌套RecyclerView,父级与子级均带Footer

嵌套RecyclerView(父+子)添加Footer的Kotlin实现方案

核心思路

不管是父级还是子级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()中根据条件返回对应数量

嵌套RecyclerView带Footer效果

内容的提问来源于stack exchange,提问作者Yash Dadhich

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.17 16:50:22