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显示效果:仅展示最后一个子节点的内容,且每个字段值单独占据一项列表,布局错乱
问题修复方案
核心问题
- 重复清空与监听器嵌套:每次遍历子节点时调用
notificationArray.clear(),清空之前数据,最终仅保留最后一个节点内容;多层嵌套addValueEventListener导致重复触发更新,逻辑混乱。 - 数据解析错误:将每个字段的单独值当作
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) { // 可添加错误日志或提示 } }) }
修复说明
- 优化监听器:用
addListenerForSingleValueEvent替代重复的addValueEventListener,避免不必要的实时更新;若需实时监听,可保留但需简化嵌套层级。 - 正确解析数据:通过
dsd.getValue(Notification::class.java)直接将Firebase节点映射为Notification对象,无需遍历子字段。 - 统一列表更新:初始化时绑定适配器,后续仅调用
notifyDataSetChanged()更新,避免重复创建适配器;外层清空列表确保每次数据都是全新集合。 - 空值安全处理:添加空值判断避免空指针异常。
内容的提问来源于stack exchange,提问作者sean
相关产品推荐
相关产品推荐

