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

Kotlin嵌套RecyclerView加载Firebase数据无法填充内容问题求助

问题定位与修复方案

核心问题列表

  • ViewModel中Firebase数据解析逻辑完全错误,未按照数据库结构提取日期和对应预约数据
  • 父适配器ParentAdapter存在多处错误:setParentItem未通知数据集刷新、子适配器实例化错误、未将Fragment传递给子适配器
  • Fragment中LiveData观察逻辑冗余,重复初始化RecyclerView配置,影响渲染效率
  • 数据模型和Firebase字段映射不匹配,未手动绑定日期节点的key为ParentOnlyDate的date字段

修复代码

1. 修正ViewModel中的数据解析逻辑

private val parentAdapterList : MutableLiveData<ArrayList<ParentOnlyDate>> by lazy {
    MutableLiveData<ArrayList<ParentOnlyDate>>().also {
        val ref = firebaseDatabase.child("Doctor").child(auth).child("History")
        ref.get().addOnSuccessListener { snapshot ->
            val completeItems : ArrayList<ParentOnlyDate> = arrayListOf()
            if(snapshot.exists()){
                // 遍历History下所有日期子节点
                for (dateSnapshot in snapshot.children){
                    val date = dateSnapshot.key // 日期节点的key就是日期值
                    // 提取该日期下所有预约条目
                    val appointList = arrayListOf<AppointConstructor>()
                    for (appointSnapshot in dateSnapshot.children){
                        val appoint = appointSnapshot.getValue(AppointConstructor::class.java)
                        appoint?.let { appointList.add(it) }
                    }
                    // 封装父条目
                    if (appointList.isNotEmpty()){
                        completeItems.add(ParentOnlyDate(date = date, data = appointList))
                    }
                }
                parentAdapterList.value = completeItems
            }else{
                println("Snapshot doesn't Exist")
                parentAdapterList.value = arrayListOf()
            }
        }
    }
}

fun getParentSubItems() : LiveData<ArrayList<ParentOnlyDate>>{
    return parentAdapterList
}

2. 修正父适配器ParentAdapter

class ParentAdapter(private val fragment : Fragment) : RecyclerView.Adapter<ParentAdapter.MyViewHolder>() {

    var list : ArrayList<ParentOnlyDate> = ArrayList()

    class MyViewHolder(view : RecyclerviewsubitemBinding) : RecyclerView.ViewHolder(view.root){
        val titleDate : TextView = view.TitleTextview
        val recyclerView : RecyclerView = view.SubRecyclerViewId
    }

    override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): MyViewHolder {
        val binding : RecyclerviewsubitemBinding = RecyclerviewsubitemBinding.inflate(LayoutInflater.from(parent.context), parent, false)
        return MyViewHolder(binding)
    }

    override fun onBindViewHolder(holder: MyViewHolder, position: Int) {
        val pd : ParentOnlyDate = list[position]
        holder.titleDate.text = pd.date
        holder.recyclerView.setHasFixedSize(true)
        holder.recyclerView.layoutManager = LinearLayoutManager(holder.itemView.context)
        // 用正确的子适配器,传递Fragment
        val childAdapter = SubItemAdapter()
        childAdapter.passingFragment(fragment)
        pd.data?.let { childAdapter.appointmentList(it as ArrayList<AppointConstructor>) }
        holder.recyclerView.adapter = childAdapter
    }

    override fun getItemCount(): Int {
        return list.size
    }

    fun setParentItem(list : ArrayList<ParentOnlyDate>){
        this.list = list
        // 新增通知刷新
        notifyDataSetChanged()
    }
}

3. 修正Fragment中LiveData观察逻辑

// 初始化阶段只设置一次RecyclerView配置
val model : HistoryViewModel by viewModels()
val adapter = ParentAdapter(this@DoctorHistory)
_binding?.RecyclerView?.apply {
    layoutManager = LinearLayoutManager(context)
    setHasFixedSize(true)
    this.adapter = adapter
}

// 只观察数据变更更新适配器
model.getParentSubItems().observe(viewLifecycleOwner) { data ->
    if (data.isNotEmpty()) {
        adapter.setParentItem(data)
    }
}

内容的提问来源于stack exchange,提问作者suhail zack

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.24 10:24:04