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

RecyclerView数据拆分显示异常:仅加载最后一条子节点数据

问题描述

修改代码后数据被拆分成单独值显示,程序本应读取每个子节点的所有数据库数据,但现在仅能获取最后一个子节点的数据,且eta_text等字段的值被拆分展示。


相关代码

页面逻辑代码

override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
        super.onViewCreated(view, savedInstanceState)

        clear_all = view.findViewById(R.id.clear_all)

        notificationView = view.findViewById(R.id.notificationList)

        notificationArray = arrayListOf()

        getNotifData()

        var linearLayoutManager = LinearLayoutManager(context)
        notificationView.layoutManager = linearLayoutManager
        notificationView.setHasFixedSize(true)
 
    }


     private fun getNotifData() {
         val user = FirebaseAuth.getInstance().currentUser
         val useremail = user!!.email

         dbref = FirebaseDatabase.getInstance().reference
         dbref.child("Students").orderByChild("email").equalTo(useremail.toString()).addValueEventListener(object : ValueEventListener{
             override fun onDataChange(snapshot: DataSnapshot) {
                 for (ds in snapshot.children) {
                     val idNumber: String? = ds.key

                     dbref.child("Notification").child(idNumber.toString()).addValueEventListener(object : ValueEventListener{
                         override fun onDataChange(dsnapshot: DataSnapshot) {
                             for (dsd in dsnapshot.children) {
                                 val key: String? = dsd.key
                                 dbref.child("Notification").child(idNumber.toString()).child(key.toString()).addValueEventListener(object : ValueEventListener{
                                     override fun onDataChange(dsnap: DataSnapshot) {
                                         notificationArray.clear()
                                         if (dsnap.exists()){

                                             for (queueSnapshot in dsnap.children){

                                                 notificationArray.add(Notification(queueSnapshot.value.toString()))
                                             }

                                             notifadapter = MyAdapter_Notification(notificationArray)
                                             notificationView.adapter = notifadapter
                                         }
                                          
                                     }

                                     override fun onCancelled(error: DatabaseError) {
                                         TODO("Not yet implemented")
                                     }
                                 })
                             }
                         }

                         override fun onCancelled(error: DatabaseError) {
                             TODO("Not yet implemented")
                         }
                     })
                 }

             }

             override fun onCancelled(error: DatabaseError) {
                 TODO("Not yet implemented")
             }

         })
     }

数据类

package com.example.sqms

data class Notification(var eta_text : String ?= null,
                        var office_name : String ?= null,
                        var time_text : String ?= null)

适配器代码

class MyAdapter_Notification (private val notificationList : ArrayList<Notification>)
    : RecyclerView.Adapter<MyAdapter_Notification.MyViewHolder>() {


    override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): MyViewHolder {

        val notificationView = LayoutInflater.from(parent.context).inflate(R.layout.notification_view,parent,false)

        return MyViewHolder(notificationView)
    }

    override fun onBindViewHolder(holder: MyViewHolder, position: Int) {

        val currentItem = notificationList[position]

        holder.eta_text.text = currentItem.eta_text
        holder.office_name.text = currentItem.office_name
        holder.time_text.text = currentItem.time_text

    }

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


    inner class MyViewHolder(notificationView : View) : RecyclerView.ViewHolder(notificationView){

        val eta_text : TextView = itemView.findViewById(R.id.eta_text)
        val office_name : TextView = itemView.findViewById(R.id.office_name)
        val time_text : TextView = itemView.findViewById(R.id.time_text)


    }
}

相关截图

  • 数据库数据:存在两个子节点,每个节点包含eta_text、office_name、time_text三个字段及对应值
  • RecyclerView显示效果:仅展示最后一个子节点的内容,且每个字段值单独占据一项列表,布局错乱

问题修复方案

核心问题

  1. 重复清空与监听器嵌套:每次遍历子节点时调用notificationArray.clear(),清空之前数据,最终仅保留最后一个节点内容;多层嵌套addValueEventListener导致重复触发更新,逻辑混乱。
  2. 数据解析错误:将每个字段的单独值当作Notification对象添加,而非直接将整个节点解析为完整的Notification实例。

修复后代码

页面逻辑代码(修正版)

override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
    super.onViewCreated(view, savedInstanceState)

    clear_all = view.findViewById(R.id.clear_all)
    notificationView = view.findViewById(R.id.notificationList)
    notificationArray = arrayListOf()

    val linearLayoutManager = LinearLayoutManager(context)
    notificationView.layoutManager = linearLayoutManager
    notificationView.setHasFixedSize(true)
    // 初始化适配器并绑定
    notifadapter = MyAdapter_Notification(notificationArray)
    notificationView.adapter = notifadapter

    getNotifData()
}

private fun getNotifData() {
    val user = FirebaseAuth.getInstance().currentUser ?: return
    val useremail = user.email ?: return

    dbref = FirebaseDatabase.getInstance().reference
    dbref.child("Students").orderByChild("email").equalTo(useremail).addValueEventListener(object : ValueEventListener{
        override fun onDataChange(snapshot: DataSnapshot) {
            // 外层清空列表,避免重复数据
            notificationArray.clear()
            for (ds in snapshot.children) {
                val idNumber = ds.key ?: continue
                // 使用单次监听器避免重复触发
                dbref.child("Notification").child(idNumber).addListenerForSingleValueEvent(object : ValueEventListener{
                    override fun onDataChange(dsnapshot: DataSnapshot) {
                        // 遍历所有Notification子节点,直接解析为对象
                        for (dsd in dsnapshot.children) {
                            val notification = dsd.getValue(Notification::class.java)
                            notification?.let {
                                notificationArray.add(it)
                            }
                        }
                        // 通知适配器更新数据
                        notifadapter.notifyDataSetChanged()
                    }

                    override fun onCancelled(error: DatabaseError) {
                        // 可添加错误日志或提示
                    }
                })
            }
        }

        override fun onCancelled(error: DatabaseError) {
            // 可添加错误日志或提示
        }
    })
}

修复说明

  1. 优化监听器:用addListenerForSingleValueEvent替代重复的addValueEventListener,避免不必要的实时更新;若需实时监听,可保留但需简化嵌套层级。
  2. 正确解析数据:通过dsd.getValue(Notification::class.java)直接将Firebase节点映射为Notification对象,无需遍历子字段。
  3. 统一列表更新:初始化时绑定适配器,后续仅调用notifyDataSetChanged()更新,避免重复创建适配器;外层清空列表确保每次数据都是全新集合。
  4. 空值安全处理:添加空值判断避免空指针异常。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.01 16:16:06