如何在应用启动时显示回收者视图?

时间:2019-07-04 16:40:26

标签: java android android-recyclerview

我曾尝试从Firebase数据库检索数据并在recyclerview中显示。 一切都进行得很完美。现在,在我的Firebase数据库中,有很多用于recyclerview的节点,每个节点都有图像链接,现在我只看到recyclerview仅在首先从firebase数据库中加载所有图像时显示。 数据库有一个字符串和long两种类型的值。 但是,直到未加载所有图像,才会显示任何文本值。在这里,我展示了我的尝试。 因此,问题在于如何逐步显示recyclerview。 是否加载了Text(“ string”)而不是为什么等待图像加载?

mAdapter = new PostAdapter(MainActivity.this);
query = PostRef
                    .orderByChild("timestamp")
                    .limitToLast(mPostsPerPage);
query.addListenerForSingleValueEvent(new ValueEventListener() {
            @Override
            public void onDataChange(DataSnapshot dataSnapshot) {
                List<Post> userModels = new ArrayList<>();


                for (DataSnapshot userSnapshot : dataSnapshot.getChildren()) {
                    String o=userSnapshot.getKey();
                    userModels.add(userSnapshot.getValue(Post.class));
                }

                mAdapter.addAll(userModels);

            }

            @Override
            public void onCancelled(DatabaseError databaseError) {
            }
        });

这是我的适配器

public class PostAdapter extends RecyclerView.Adapter<PostHolder>
{
    List<Post> mPost;
    Context mContext;
    Boolean likecheck=false;

    public PostAdapter(Context c) {
        this.mPost  = new ArrayList<>();
        mContext=c;
    }

    @NonNull
    @Override
    public PostHolder onCreateViewHolder(@NonNull ViewGroup viewGroup, int i) {
        return new PostHolder(LayoutInflater.from(viewGroup.getContext())
                .inflate(R.layout.all_post_layout, viewGroup, false));

    }
@Override
    public void onBindViewHolder(@NonNull final PostHolder postHolder, final int i) {
        postHolder.setData(mPost.get(i));
        final String PostKey=mPost.get(i).getPostid();
        FirebaseAuth mAuth=FirebaseAuth.getInstance();
        final String currentUserID=mAuth.getCurrentUser().getUid();
        final DatabaseReference post=FirebaseDatabase.getInstance().getReference().child("Posts");
post.child(PostKey).child("postimg").addValueEventListener(new ValueEventListener() {
            @Override
            public void onDataChange(@NonNull DataSnapshot dataSnapshot)
            {
                if (dataSnapshot.exists())
                {
                    for (DataSnapshot dataSnapshot1:dataSnapshot.getChildren())
                    {
                        String postimagelink =dataSnapshot1.getValue().toString();
                        postimagelist.add(postimagelink);
                    }


                    String[] urls =postimagelist.toArray(new String[postimagelist.size()]);
                    postHolder.mPager.setAdapter(new SlidingImage_Adapter(mContext,urls));

                    postHolder.indicator.setViewPager(postHolder.mPager);

                    final float density = mContext.getResources().getDisplayMetrics().density;
                    postHolder.indicator.setRadius(5 * density);

                    postHolder.NUM_PAGES = urls.length;



                    postHolder.indicator.setOnPageChangeListener(new ViewPager.OnPageChangeListener()
                    {

                        @Override
                        public void onPageSelected(int position) {
                            postHolder.currentPage = position;
                        }

                        @Override
                        public void onPageScrolled(int pos, float arg1, int arg2) {
                        }

                        @Override
                        public void onPageScrollStateChanged(int pos) {
                        }
                    });
                }
            }

            @Override
            public void onCancelled(@NonNull DatabaseError databaseError) {

            }
        });
@Override
    public int getItemCount() {
        return mPost.size();
    }
    public void addAll(List<Post> newPost) {
        int initialSize = mPost.size();
        mPost.addAll(newPost);
        notifyItemRangeInserted(initialSize, newPost.size());
    }

    public String getLastItemId() {
        return mPost.get(mPost.size() - 1).getPostid();
    }

}

观看者

public class PostHolder extends RecyclerView.ViewHolder
{
    AutoLinkTextView description;
    TextView postfullname;
ViewPager mPager;
        int currentPage = 0;
        int NUM_PAGES = 0;
        CirclePageIndicator indicator;
        Context context;
public PostHolder(@NonNull View itemView) {
        super(itemView);

         postfullname = itemView.findViewById(R.id.user_post_full_name);
         description = itemView.findViewById(R.id.user_post_description);

         mPager = (ViewPager) itemView.findViewById(R.id.pager);
         indicator = (CirclePageIndicator)itemView.findViewById(R.id.indicator);

    }
    public void setData(Post post)
    {
        description.setText(post.getDescription());
        postfullname.setText(post.getFirstname()+" "+post.getLastname());
    }
}

enter image description here

2 个答案:

答案 0 :(得分:0)

好的,我发现您的适配器有几个问题。

第一

 public void addAll(List<Post> newPost) {
        int initialSize = mPost.size();
        mPost.addAll(newPost);
        notifyItemRangeInserted(initialSize, newPost.size());
    }

在这里,您要传递一个Post列表作为参数,您正在使用mPost.size(),在那儿什么也不做,可以用add代替addAll方法,而newPost.size()可以为空以及mPost.size()

第二

@Override
    public int getItemCount() {
        return mPost.size();
    }

如果列表为空,您也应该处理

@Override
    public int getItemCount() {
        if(mPost.size() > 0){
          return mPost.size();
         }else{
           return 0;
           }
    }

第三

onBindViewHolder中的所有firebase代码都是错误的,因为在将数据绑定到每一行时,您还试图每次使用firebase来获取值。这样做将导致多个firebase调用仅获取1行数据,而不是获取要显示的所有数据。

解决方案是在您的主要活动中执行所有Firebase逻辑,并将数据传递给适配器以设置值。

要使用更简洁的方法解决此问题,请将Array作为参数传递给Adapter Constructor,删除addAll方法,然后执行此操作。

 public PostAdapter(Context c, List<Post> mPost) {
        this.mPost  = mPost
        mContext=c;
    }

然后,如我所说,从您的onBindViewHolder中删除所有firebase代码,并将其放入您的MainActivity

更改了适配器的构造函数后,您现在应该使用从firebase提取的数据来与适配器一起使用。

query = PostRef
                    .orderByChild("timestamp")
                    .limitToLast(mPostsPerPage);
query.addListenerForSingleValueEvent(new ValueEventListener() {
            @Override
            public void onDataChange(DataSnapshot dataSnapshot) {
                List<Post> userModels = new ArrayList<>();


                for (DataSnapshot userSnapshot : dataSnapshot.getChildren()) {
                    String o=userSnapshot.getKey();
                    userModels.add(userSnapshot.getValue(Post.class));
                }

                mAdapter = new PostAdapter(MainActivity.this,userModels)

            }

            @Override
            public void onCancelled(DatabaseError databaseError) {
            }
        });

如果您想将任何更改通知您的适配器。只需对适配器进行全局声明,例如

private PostAdapter adapter;

然后使用

adapter.notifySetDataChanged(); 

确保实例至少已执行一次。

mAdapter = new PostAdapter(MainActivity.this,userModels);

答案 1 :(得分:0)

Firebase已发布firebaseRecyclerViewAdapter类。这将为您完成很多工作。

适配器采用4个输入参数:

  • 对象类
  • 列出项目布局资源
  • Viewholder类
  • 查询/ firebase参考

仅需populateViewHolder方法

FirebaseRecyclerViewAdapter<Object, ObjectViewHolder> adapter = new FirebaseRecyclerViewAdapter<Object, ObjectViewHolder>
(Object.class, android.R.layout.*list_item_layout*, ObjectViewHolder.class, objectQuery) {
    public void populateViewHolder(ObjectViewHolder ObjectViewHolder, Object Object) {

    //populate your views, example:
        ObjectViewHolder.textview.setText(object.getTextOne());

    }
};

然后设置适配器:

recycler.setAdapter(mAdapter);

有关此Firebase RecyclerView Adapter

的更多信息