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

如何在RecyclerView的单个item中嵌套展示ChildQuestionList子列表?

嘿,我来帮你搞定这个嵌套RecyclerView的问题!你现在遇到的核心问题是适配器没有正确处理父Item的子列表展示,而且不想重新初始化适配器对吧?下面是具体的实现步骤,都是Android开发里常用的方案:

解决方案:实现带动态子列表的嵌套RecyclerView(无需重建适配器)

1. 先把数据模型和适配器结构捋顺

首先,你的父Question模型得能容纳子列表,还要有方法动态更新子数据,这样不用动整个父列表:

public class Question {
    private String parentQuestion;
    private List<ChildQuestion> childQuestionList;

    // 构造器、getter方法自行补充
    // 关键:给子列表加个更新方法
    public void updateChildList(List<ChildQuestion> newChilds) {
        this.childQuestionList = newChilds;
    }
}

然后,父RecyclerView的每个Item布局里要嵌套一个子RecyclerView,用来展示对应的ChildQuestionList。比如父Item的布局item_parent_question.xml大概是这样:

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:orientation="vertical">

    <TextView
        android:id="@+id/tv_parent_question"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:padding="16dp"
        android:textSize="18sp"/>

    <androidx.recyclerview.widget.RecyclerView
        android:id="@+id/rv_child_questions"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:paddingStart="32dp"/>
</LinearLayout>

2. 改造父适配器,支持子列表动态更新

父适配器的核心是在绑定每个父Item时,给子RecyclerView设置适配器,并且提供单独更新子列表的方法,不用刷新整个父列表:

public class ParentQuestionAdapter extends RecyclerView.Adapter<ParentQuestionAdapter.ParentViewHolder> {
    private List<Question> mParentList;

    public ParentQuestionAdapter(List<Question> parentList) {
        this.mParentList = parentList;
    }

    // 重点:这个方法用来更新指定父Item的子列表,不用重建适配器
    public void refreshChildList(int parentPos, List<ChildQuestion> newChilds) {
        Question targetParent = mParentList.get(parentPos);
        targetParent.updateChildList(newChilds);
        // 只通知这个位置的Item更新,比notifyDataSetChanged()高效太多
        notifyItemChanged(parentPos);
    }

    @Override
    public void onBindViewHolder(@NonNull ParentViewHolder holder, int position) {
        Question currentParent = mParentList.get(position);
        holder.tvParent.setText(currentParent.getParentQuestion());

        // 给子RecyclerView设置适配器,直接用当前父Item的子列表数据
        ChildQuestionAdapter childAdapter = new ChildQuestionAdapter(currentParent.getChildQuestionList());
        holder.rvChild.setAdapter(childAdapter);
        holder.rvChild.setLayoutManager(new LinearLayoutManager(holder.itemView.getContext()));
        holder.rvChild.setHasFixedSize(true);
    }

    static class ParentViewHolder extends RecyclerView.ViewHolder {
        TextView tvParent;
        RecyclerView rvChild;

        public ParentViewHolder(@NonNull View itemView) {
            super(itemView);
            tvParent = itemView.findViewById(R.id.tv_parent_question);
            rvChild = itemView.findViewById(R.id.rv_child_questions);
        }
    }
}

子适配器就是普通的RecyclerView适配器,用来展示子问答:

public class ChildQuestionAdapter extends RecyclerView.Adapter<ChildQuestionAdapter.ChildViewHolder> {
    private List<ChildQuestion> mChildList;

    public ChildQuestionAdapter(List<ChildQuestion> childList) {
        this.mChildList = childList;
    }

    @Override
    public void onBindViewHolder(@NonNull ChildViewHolder holder, int position) {
        ChildQuestion child = mChildList.get(position);
        holder.tvChildQ.setText(child.getQuestion());
        holder.tvChildA.setText(child.getAnswer());
    }

    static class ChildViewHolder extends RecyclerView.ViewHolder {
        TextView tvChildQ;
        TextView tvChildA;

        public ChildViewHolder(@NonNull View itemView) {
            super(itemView);
            tvChildQ = itemView.findViewById(R.id.tv_child_question);
            tvChildA = itemView.findViewById(R.id.tv_child_answer);
        }
    }
}

3. 动态更新子列表的正确操作

当你拿到某个父Item的子列表数据后(比如网络请求返回),直接调用父适配器的refreshChildList方法就行,完全不用重新创建适配器:

// 假设你拿到了第0个父Item的子列表数据
List<ChildQuestion> newChildData = ...; // 你的动态子问答数据
mParentAdapter.refreshChildList(0, newChildData);

4. 解决只显示第0个父Item的问题

你说适配器只运行一次,只展示第0个对象,大概率是这两个原因:

  • 父RecyclerView没设置布局管理器!一定要加这句:
mParentRecyclerView.setLayoutManager(new LinearLayoutManager(this));
  • 初始化questionList的时候只放了第0个父对象?检查下你的数据源,确保所有要展示的父Question都在列表里。如果是动态加载父列表,用notifyItemInserted()来添加新Item,别重建适配器。

额外小技巧

  • 如果需要子列表展开/收起的功能,可以给父Item加点击事件,控制子RecyclerView的visibility(GONE/VISIBLE),记得在适配器里保存每个父Item的展开状态,避免滚动后状态丢失。
  • 数据量大的话,用DiffUtil来优化更新性能,减少不必要的视图刷新。

内容的提问来源于stack exchange,提问作者Ajay Mehta

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.15 06:53:24