Android Studio中onCreateViewHolder内getRef(position)无法识别求助
getRef()方法不识别的问题 嘿,我来帮你搞定这个问题!你遇到的getRef()方法不被识别的问题,根源很简单——你目前用的是普通的RecyclerView.Adapter,而getRef()是Firebase官方提供的FirebaseRecyclerAdapter才有的专属方法。不过别担心,有两种简单的解决办法,我一步步给你讲:
方法一:从数据源直接存储并获取用户ID(推荐新手使用)
这个方法不需要改动太多现有代码,核心思路是把Firebase节点的key(也就是你要的visit_user_id)直接存在你的MyDataGetSet数据类里,之后点击的时候直接从对应的数据对象中取出即可。
步骤1:给MyDataGetSet添加user_id字段
修改你的MyDataGetSet类,增加user_id属性和对应的getter/setter方法(Firebase需要空构造函数,别忘了保留):
public class MyDataGetSet { // 你原来的字段 private String user_name; private String user_status; private String user_thumb_image; // 新增的user_id字段,用来存储Firebase节点的key private String user_id; // Firebase必须的空构造函数 public MyDataGetSet() {} // 带所有参数的构造函数(根据你的需求调整) public MyDataGetSet(String user_name, String user_status, String user_thumb_image, String user_id) { this.user_name = user_name; this.user_status = user_status; this.user_thumb_image = user_thumb_image; this.user_id = user_id; } // 生成user_id的getter方法 public String getUser_id() { return user_id; } // 生成user_id的setter方法 public void setUser_id(String user_id) { this.user_id = user_id; } // 你原来的其他getter/setter方法... }
步骤2:在获取Firebase数据时保存key
修改onChildAdded方法,把当前数据节点的key赋值给MyDataGetSet对象:
@Override public void onChildAdded(DataSnapshot dataSnapshot, String s) { MyDataGetSet data = dataSnapshot.getValue(MyDataGetSet.class); // 把Firebase节点的key设置给data对象 data.setUser_id(dataSnapshot.getKey()); listData.add(data); // 这里建议用notifyDataSetChanged更新列表,而不是重复调用setAdapter adapter.notifyDataSetChanged(); }
小提示:你可以把
myRecyclerView.setAdapter(adapter);移到onCreate方法的末尾,初始化的时候设置一次就够了,不需要每次添加数据都设置。
步骤3:在点击事件中获取ID
修改onBindViewHolder里的点击事件,直接从当前位置的数据对象中取出user_id:
holder.itemView.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { // 从当前位置的data对象中获取user_id String visit_user_id = listArray.get(position).getUser_id(); Intent profileIntend = new Intent(Main2Activity.this, ProfileActivity.class); profileIntend.putExtra("visit_user_id", visit_user_id); startActivity(profileIntend); } });
方法二:改用FirebaseRecyclerAdapter(官方适配方案)
如果你想直接使用getRef()方法,可以换成Firebase官方提供的FirebaseRecyclerAdapter,它内置了和Firebase数据库同步的逻辑,也自带getRef()方法。
步骤1:添加Firebase UI依赖
在你的build.gradle(Module: app)文件中添加Firebase UI的依赖(版本要和你使用的Firebase SDK版本匹配,这里以8.0.0为例):
dependencies { // 你的其他依赖... implementation 'com.firebaseui:firebase-ui-database:8.0.0' }
步骤2:替换自定义Adapter为FirebaseRecyclerAdapter
把你原来的MyAdapter替换成下面的代码:
public class MyAdapter extends FirebaseRecyclerAdapter<MyDataGetSet, MyAdapter.MyViewHolder> { private Context context; // 构造函数接收FirebaseRecyclerOptions和上下文 public MyAdapter(@NonNull FirebaseRecyclerOptions<MyDataGetSet> options, Context context) { super(options); this.context = context; } @NonNull @Override public MyViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) { View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.itemview, parent, false); return new MyViewHolder(view); } @Override protected void onBindViewHolder(@NonNull MyViewHolder holder, int position, @NonNull MyDataGetSet model) { holder.MyText.setText(model.getUser_name()); holder.MyStatus.setText(model.getUser_status()); Picasso.with(context).load(model.getUser_thumb_image()).into(holder.MyImage); holder.itemView.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { // 现在可以直接使用getRef()方法获取节点key了 String visit_user_id = getRef(position).getKey(); Intent profileIntend = new Intent(Main2Activity.this, ProfileActivity.class); profileIntend.putExtra("visit_user_id", visit_user_id); startActivity(profileIntend); } }); } public class MyViewHolder extends RecyclerView.ViewHolder { TextView MyText; TextView MyStatus; CircleImageView MyImage; public MyViewHolder(View itemView) { super(itemView); MyText = itemView.findViewById(R.id.TextView); MyStatus = itemView.findViewById(R.id.TextStatus); MyImage = itemView.findViewById(R.id.TextImage); } } }
步骤3:修改Activity中的初始化逻辑
调整onCreate和GetDataFirebase方法,同时记得在onStart和onStop中启动/停止Firebase数据监听:
@Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main2); // ... 你的其他初始化代码(Toolbar、RecyclerView设置等)不变 GetDataFirebase(); } void GetDataFirebase(){ DBR = FDB.getReference("Users"); // 配置FirebaseRecyclerOptions,指定查询和数据模型 FirebaseRecyclerOptions<MyDataGetSet> options = new FirebaseRecyclerOptions.Builder<MyDataGetSet>() .setQuery(DBR, MyDataGetSet.class) .build(); // 创建Adapter并设置给RecyclerView adapter = new MyAdapter(options, getApplicationContext()); myRecyclerView.setAdapter(adapter); } // 启动Activity时开始监听Firebase数据 @Override protected void onStart() { super.onStart(); adapter.startListening(); } // 停止Activity时停止监听,避免内存泄漏 @Override protected void onStop() { super.onStop(); adapter.stopListening(); }
为什么原来的getRef()会报错?
普通的RecyclerView.Adapter是Android SDK自带的组件,它不知道Firebase数据库的存在,自然没有getRef()这个方法。而FirebaseRecyclerAdapter是Firebase官方为了简化开发者操作而封装的Adapter,内置了和Firebase数据库交互的逻辑,所以才提供了getRef()来快速获取节点key。
内容的提问来源于stack exchange,提问作者SURIAN B M BIT

