如何通过Adapter传静态变量并解决Firebase序列化与RecyclerView错误
解决你的Firebase与RecyclerView问题
嘿,我来帮你搞定这两个困扰你两天的问题,咱们一步步拆解解决:
1. 首先解决Firebase的序列化异常(No properties to serialize found)
问题原因
Firebase Realtime Database在序列化/反序列化Java对象时,只会识别实例级别的字段和方法(也就是不带static修饰符的)。你把Users类里的所有字段、getter和setter都设成了static,这意味着这些属性属于Users类本身,而不是每个独立的Users实例。Firebase找不到可用于序列化的实例属性,所以抛出了这个异常。
修复方案
把Users类中所有的static修饰符全部移除,让字段和方法属于实例:
修改后的Users.java:
package com.example.login; public class Users { private String UserName; private String UserPhone; private String UserDesc; private String UserEmail; private String UserID; public Users(String userName,String userPhone,String userDesc,String userEmail, String userID) { this.UserName = userName; this.UserPhone = userPhone; this.UserDesc = userDesc; this.UserEmail = userEmail; this.UserID = userID; } public Users() { } public String getUserName() { return UserName; } public void setUserName(String userName) { UserName = userName; } public String getUserPhone() { return UserPhone; } public void setUserPhone(String userPhone) { UserPhone = userPhone; } public String getUserDesc() { return UserDesc; } public void setUserDesc(String userDesc) { UserDesc = userDesc; } public String getUserEmail() { return UserEmail; } public void setUserEmail(String userEmail) { UserEmail = userEmail; } public String getUserID() { return UserID; } public void setUserID(String userID) { UserID = userID; } }
2. 解决RecyclerView的警告(No adapter attached; skipping layout)
问题原因
RecyclerView在初始化完成后,你没有立即给它设置adapter,而是等到Firebase的onDataChange回调触发后才设置。如果数据加载有延迟(比如网络慢),RecyclerView在首次绘制时就会因为没有adapter而抛出这个警告。
修复方案
在onCreateView中初始化完users列表后,先创建一个空的UserAdapter并设置给RecyclerView;同时还要修正你原来的用户判断逻辑(原来调用静态方法的方式是错误的,现在要调用实例方法)。
修改后的UsersFragment.java关键部分:
@Override public View onCreateView(LayoutInflater inflater,ViewGroup container, Bundle savedInstanceState) { View view = inflater.inflate(R.layout.fragment_users,container,false); recyclerView = view.findViewById(R.id.user_recycler); recyclerView.setHasFixedSize(true); recyclerView.setLayoutManager(new LinearLayoutManager(getContext())); users = new ArrayList<>(); // 先设置空的adapter,避免警告 userAdapter = new UserAdapter(getContext(), users); recyclerView.setAdapter(userAdapter); readUsers(); return view; } private void readUsers() { final FirebaseUser firebaseUser = FirebaseAuth.getInstance().getCurrentUser(); DatabaseReference reference = FirebaseDatabase.getInstance().getReference("Users"); reference.addValueEventListener(new ValueEventListener() { @Override public void onDataChange(@NonNull DataSnapshot dataSnapshot) { users.clear(); for(DataSnapshot snapshot : dataSnapshot.getChildren()){ Users user = snapshot.getValue(Users.class); assert firebaseUser != null; // 修正:调用实例的getUserID方法,而不是类的静态方法 if(user != null && !user.getUserID().equals(firebaseUser.getUid())){ users.add(user); Log.d("hhh",String.valueOf(users)); } } // 数据更新后通知adapter刷新 userAdapter.notifyDataSetChanged(); } @Override public void onCancelled(@NonNull DatabaseError databaseError) { } }); }
额外说明
- 我在
onDataChange里加了user != null的判断,避免因为反序列化失败导致空指针异常; - 现在不需要重新创建
userAdapter,只需要更新users列表后调用notifyDataSetChanged()即可刷新RecyclerView,这样性能更好。
内容的提问来源于stack exchange,提问作者Pratik Bharad
相关产品推荐
相关产品推荐

