如何将数据从 Firebase 检索到我的适配器
Posted
技术标签:
【中文标题】如何将数据从 Firebase 检索到我的适配器【英文标题】:How can I retrieve data from Firebase to my adapter 【发布时间】:2018-08-29 05:40:12 【问题描述】:我的结构
所以我有一个应用程序,用户可以在我的适配器中上传帖子。我可以检索帖子描述和帖子图片,但是当我尝试检索海报的名称时,应用程序似乎崩溃了,为了检索每个帖子的名称,数据库中添加了一个带有上传者 ID 的子项。这是我的类文件:
public String image_thumb;
public String user_id;
public String image_url;
public String desc;
public BlogPost()
public BlogPost(String user_id, String image_url, String desc, String image_thumb)
this.user_id = user_id;
this.image_url = image_url;
this.desc = desc;
this.image_thumb = image_thumb;
public String getUser_id()
return user_id;
public void setUser_id(String user_id)
this.user_id = user_id;
public String getImage_url()
return image_url;
public void setImage_url(String image_url)
this.image_url = image_url;
public String getDesc()
return desc;
public void setDesc(String desc)
this.desc = desc;
public String getImage_thumb()
return image_thumb;
public void setImage_thumb(String image_thumb)
this.image_thumb = image_thumb;
这是我的一些适配器:
public void onBindViewHolder(final ViewHolder holder, int position)
String desc_data = blog_list.get(position).getDesc();
holder.setDescText(desc_data);//this works
String image_url = blog_list.get(position).getImage_url();
holder.setBlogImage(image_url);//this works
String user_id = blog_list.get(position).getUser_id();
firebaseDatabase.child("Users").child(user_id).addValueEventListener(new ValueEventListener()
@Override
public void onDataChange(DataSnapshot dataSnapshot)
if(dataSnapshot.exists())
String userName = dataSnapshot.child("name").getValue().toString();
holder.setUserName(userName);
@Override
public void onCancelled(DatabaseError databaseError)
);
public void setUserName(String name)
blogUserName = mView.findViewById(R.id.blog_user_name);
blogUserName.setText(name);
我基本上想做的是在 user_id 中查找名称并在我的 TextView
中检索它
【问题讨论】:
请分享您的数据库的结构,这里也使用它 我添加了结构 显示你初始化(firebaseDatabase)的代码。 这只是 FirebaseDatabase.getInstance().getReferance(); 错误在哪一行。 【参考方案1】: public void checklocation()
recyclerView=findViewById(R.id.recy);
FirebaseDatabase database = FirebaseDatabase.getInstance();
databaseReference = database.getReference();
databaseReference.addValueEventListener(new ValueEventListener()
@Override
public void onDataChange(@NonNull @NotNull DataSnapshot snapshot)
for (DataSnapshot snapshot1: snapshot.getChildren())
Model_lats model_lats=snapshot1.child("location").getValue(Model_lats.class);
latslist.add(model_lats);
adapter_lats=new Adapter_lats(MapsActivity.this,latslist);
recyclerView.setAdapter(adapter_lats);
adapter_lats.notifyDataSetChanged();
@Override
public void onCancelled(@NonNull @NotNull DatabaseError error)
Toast.makeText(MapsActivity.this, "cant read"+error, Toast.LENGTH_SHORT).show();
);
【讨论】:
【参考方案2】:为了使其正常工作,我建议您在模型类和代码中进行一些更改。您的模型类应如下所示:
public class BlogPost
public String imageThumb, userId, imageUrl, desc;
public BlogPost()
public BlogPost(String imageThumb, String userId, String imageUrl, String desc)
this.imageThumb = imageThumb;
this.userId = userId;
this.imageUrl = imageUrl;
this.desc = desc;
public String getImageThumb() return imageThumb;
public String getUserId() return userId;
public String getImageUrl() return imageUrl;
public String getDesc() return desc;
请参阅字段和 getter 的命名约定。
为了使它工作,不要忘记删除旧数据并添加新数据。
假设您的活动有一个 .XML 文件,其中包含一个 RecyclerView
,如下所示:
<android.support.v7.widget.RecyclerView
android:layout_
android:layout_
android:id="@+id/recycler_view"/>
还有一个用于项目文件的 .XML 文件,如下所示:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_
android:layout_
android:orientation="horizontal">
<TextView
android:layout_
android:layout_
android:id="@+id/image_thumb_text_view" />
<TextView
android:layout_
android:layout_
android:id="@+id/user_id_text_view" />
<TextView
android:layout_
android:layout_
android:id="@+id/image_url_text_view" />
<TextView
android:layout_
android:layout_
android:id="@+id/desc_text_view" />
</LinearLayout>
要使用FriebaseRecyclerAdapter
在RecyclerView
中显示您的数据,请按照以下步骤操作:
首先,您需要在您的活动中找到RecyclerView
,然后像这样设置LinearLayoutManager
:
RecyclerView recyclerView = findViewById(R.id.recycler_view);
recyclerView.setLayoutManager(new LinearLayoutManager(this));
然后您需要创建 Firebase 数据库的根引用和一个 Query
对象,如下所示:
DatabaseReference rootRef = FirebaseDatabase.getInstance().getReference();
Query query = rootRef.child("Users");
然后你必须像这样创建一个FirebaseRecyclerOptions
对象:
FirebaseRecyclerOptions<BlogPost> firebaseRecyclerOptions = new FirebaseRecyclerOptions.Builder<BlogPost>()
.setQuery(query, BlogPost.class)
.build();
在您的活动类中,创建一个如下所示的holder
类:
private class BlogPostHolder extends RecyclerView.ViewHolder
private TextView imageThumbtextView, userIdTextView, imageUrlTextView, descTextView;
BlogPostHolder(View itemView)
super(itemView);
imageThumbtextView = itemView.findViewById(R.id.image_thumb_text_view);
userIdTextView = itemView.findViewById(R.id.user_id_text_view);
imageUrlTextView = itemView.findViewById(R.id.image_url_text_view);
descTextView = itemView.findViewById(R.id.desc_text_view);
void setBlogPost(BlogPost blogPost)
String imageThumb = blogPost.getImageThumb();
imageThumbtextView.setText(imageThumb);
String userId = blogPost.getUserId();
userIdTextView.setText(userId);
String imageUrl = blogPost.getImageUrl();
imageUrlTextView.setText(imageUrl);
String desc = blogPost.getDesc();
descTextView.setText(desc);
然后创建一个声明为全局的适配器:
private FirebaseRecyclerAdapter<BlogPost, BlogPostHolder> firebaseRecyclerAdapter;
并像这样在您的活动中实例化它:
firebaseRecyclerAdapter = new FirebaseRecyclerAdapter<BlogPost, BlogPostHolder>(firebaseRecyclerOptions)
@Override
protected void onBindViewHolder(@NonNull BlogPostHolder blogPostHolder, int position, @NonNull BlogPost blogPost)
blogPostHolder.setBlogPost(blogPost);
@Override
public BlogPostHolder onCreateViewHolder(ViewGroup parent, int viewType)
View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.item, parent, false);
return new BlogPostHolder(view);
;
recyclerView.setAdapter(firebaseRecyclerAdapter);
最后别忘了重写以下两个方法,开始监听变化:
@Override
protected void onStart()
super.onStart();
firebaseRecyclerAdapter.startListening();
@Override
protected void onStop()
super.onStop();
if (firebaseRecyclerAdapter!= null)
firebaseRecyclerAdapter.stopListening();
【讨论】:
实际上像你一样改变我的班级有帮助:) 非常感谢。 所以我在两个地方尝试了这个,我的活动和我的片段。这对我的活动非常有效,我似乎无法弄清楚为什么它对我的片段不起作用。 @AlexMamo @Kristofer 你有错误吗?行为是什么?我建议您添加一个包含mcve 的新问题,以便我或其他用户可以帮助您解决问题。 我已经发布了link@AlexMamo 嗨@AlexMamo,按照步骤我发现我的onBindViewHolder 有问题。它说我的“blogPostHolder.setBlogPost(blogPost) 不能从静态上下文中引用,但是将 'setBlogPost(错误来自哪里)设为静态只会使我的 textview 出现在持有人错误中。我是否将 onBindViewHolder 放在错误的地方?它目前不是我的 OnCreate 而不是我需要回收站的活动。【参考方案3】:下面的代码在这一行下面的 onBindviewhoder() 中:
String user_id = . . .. . . .
我猜这是您引用数据的方式以及附加侦听器的方式。尝试像这样初始化数据库引用:
DatabaseReference firebaseDatabase= FirebaseDatabase.getInstance().getReference().child("Users").child(user_id);
现在试着像这样听:
firebaseDatabase.addValueEventListener(new ValueEvent....
onDataChange(.....)
//your same code
)
【讨论】:
【参考方案4】:最好不要在 ViewBinder 中包含任何用于回收站视图的 firebase 调用。 您可以做的是更新您的 BlogPost 并包含一个带有 getter 和 setter 的字段名称。然后在您将 BlogPost 添加到回收器适配器的活动中,您可以获取用户名,将名称添加到博客文章并通知适配器数据更改。
在你的活动中这样做
// adding BlogPost to list
// Create BlogPost object with the data.
blogList.add(blogPostObject)
firebaseDatabase.child("Users").child(user_id).child("name").addListenerForSingleValueEvent(new ValueEventListener()
@Override
public void onDataChange(DataSnapshot dataSnapshot)
if(dataSnapshot.exists())
blogPostObject.setName(dataSnapshot.getValue().toString());
adapter..notifyItemChanged(indexOfblogPostObject);
@Override
public void onCancelled(DatabaseError databaseError)
);
【讨论】:
以上是关于如何将数据从 Firebase 检索到我的适配器的主要内容,如果未能解决你的问题,请参考以下文章
如何从 Firebase 检索数据到 ListView(使用自定义数组适配器)
我正在尝试将 firebase 实时数据库中的数据检索到我的 recyclerview 中,但数据显示为空