【问题标题】:How can I retrieve data from Firebase to my adapter如何将数据从 Firebase 检索到我的适配器
【发布时间】: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();
  • 错误在哪一行。

标签: android firebase firebase-realtime-database


【解决方案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_width="match_parent"
        android:layout_height="match_parent"
        android:id="@+id/recycler_view"/>
    

    还有一个用于项目文件的 .XML 文件,如下所示:

    <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:orientation="horizontal">
    
        <TextView
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:id="@+id/image_thumb_text_view" />
    
        <TextView
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:id="@+id/user_id_text_view" />
    
        <TextView
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:id="@+id/image_url_text_view" />
    
        <TextView
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            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) {
      
              }
          });
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2020-11-05
        • 2023-04-03
        • 1970-01-01
        • 2016-12-18
        • 2019-04-04
        • 2019-09-11
        • 1970-01-01
        相关资源
        最近更新 更多