RecyclerView报错No adapter attached及Firebase数据解析问题求助
解决Firebase数据解析错误与RecyclerView无适配器问题
一、修复snaps.getValue(Users::class.java)解析错误
问题原因
- 你用普通
class定义Users,Firebase需要类具备序列化/反序列化能力,普通类缺少默认的getter/setter及序列化支持; - 数据库字段名可能和类属性名不匹配;
- 强制非空断言
!!会在解析失败时直接崩溃,没有容错处理。
修复方案
- 将
Users改为数据类(data class),Kotlin数据类会自动生成序列化所需方法:
data class Users ( var userId: String? = null, var password: String? = null )
- 确保Firebase数据库中的字段名和类属性名完全一致(比如数据库节点下的键是
userId、password),如果字段名不匹配,用@PropertyName注解映射:
import com.google.firebase.database.PropertyName data class Users ( @PropertyName("user_id") // 对应数据库里的user_id字段 var userId: String? = null, @PropertyName("user_pwd") // 对应数据库里的user_pwd字段 var password: String? = null )
- 去掉强制非空断言,做空安全判断:
val userData = snaps.getValue(Users::class.java) userData?.let { userList.add(it) }
二、修复RecyclerView No adapter attached; skipping layout错误
问题原因
Firebase的addValueEventListener是异步回调,初始化RecyclerView时还没拿到数据,此时RecyclerView没有绑定adapter,系统会抛出警告。
修复方案
- 初始化RecyclerView时就设置空adapter,不要等数据加载完成再设置:
// MainActivity初始化代码 firebaseAuth = FirebaseAuth.getInstance() userRecyclerView = findViewById(R.id.recyclerView) userRecyclerView.layoutManager = LinearLayoutManager(this) userRecyclerView.hasFixedSize() userList = arrayListOf<Users>() // 提前绑定空adapter val mAdapter = UserAdapter(userList) userRecyclerView.adapter = mAdapter getUserList()
- 数据加载完成后,直接更新现有adapter的数据并通知刷新,不要重新创建adapter:
private fun getUserList() { dbref = FirebaseDatabase.getInstance().getReference("User") dbref.addValueEventListener(object : ValueEventListener{ override fun onDataChange(snapshot: DataSnapshot) { userList.clear() if(snapshot.exists()){ for (snaps in snapshot.children){ val userData = snaps.getValue(Users::class.java) userData?.let { userList.add(it) } } // 通知adapter数据更新 userRecyclerView.adapter?.notifyDataSetChanged() } } override fun onCancelled(error: DatabaseError) { // 建议添加错误日志,方便排查问题 Log.e("FirebaseError", error.message) } }) }
- 类名遵循Kotlin命名规范,把
adapter改为首字母大写的UserAdapter:
class UserAdapter(private val userList: ArrayList<Users>) : RecyclerView.Adapter<UserAdapter.ViewHolder>() { override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder { val itemView = LayoutInflater.from(parent.context).inflate(R.layout.users, parent, false) return ViewHolder(itemView) } override fun onBindViewHolder(holder: ViewHolder, position: Int) { val current = userList[position] holder.userID.text = current.userId } override fun getItemCount(): Int { return userList.size } class ViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) { val userID: TextView = itemView.findViewById(R.id.userTv) } }
内容的提问来源于stack exchange,提问作者Ankit Laller
相关产品推荐
相关产品推荐

