[英]How to display recycler view on start of app?
I had tried to retrieve data from firebase database and show in recyclerview. 我曾尝试从Firebase数据库检索数据并在recyclerview中显示。 Everything is going perfect. 一切都进行得很完美。 Now in my firebase database has lots of node for recyclerview and each node has image link and now i just seen that recyclerview only show when all images are loaded from firebase database first. 现在,在我的Firebase数据库中,有很多用于recyclerview的节点,每个节点都有图像链接,现在我只看到recyclerview仅在首先从firebase数据库中加载所有图像时显示。 Database has a string and long both types of values. 数据库有一个字符串和long两种类型的值。 But No any text values display until all images are not loaded. 但是,直到未加载所有图像,才会显示任何文本值。 Here i shows what am i tried. 在这里,我展示了我的尝试。 So the question is how to show recyclerview step by step. 因此,问题在于如何逐步显示recyclerview。 if Text("string") is loaded than why it waiting for images loading? 如果要加载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) {
}
});
this is my adapter 这是我的适配器
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();
}
}
viewholder 观看者
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());
}
}
Ok, I see a couple of problems with your adapter. 好的,我发现您的适配器有几个问题。
First 第一
public void addAll(List<Post> newPost) {
int initialSize = mPost.size();
mPost.addAll(newPost);
notifyItemRangeInserted(initialSize, newPost.size());
}
Here, you are passing a list of Post as a parameter, you are using mPost.size()
wich will not do anything there, the addAll method can be replaced with just add and the newPost.size()
could be empty as well as the mPost.size()
在这里,您要传递一个Post列表作为参数,您正在使用mPost.size()
,在那儿什么也不做,addAll方法可以替换为add,而newPost.size()
可以为空以及mPost.size()
Second 第二
@Override
public int getItemCount() {
return mPost.size();
}
You should also handle if the list is empty 如果列表为空,也应该处理
@Override
public int getItemCount() {
if(mPost.size() > 0){
return mPost.size();
}else{
return 0;
}
}
Third 第三
All your firebase code inside your onBindViewHolder
is wrong because while you are binding the data into each row, you are also trying to get each time the values with firebase. 您将onBindViewHolder
内的所有onBindViewHolder
代码都错了,因为将数据绑定到每一行时,您还试图每次使用firebase来获取值。 Doing this will lend to multiple firebase calls to get the data for just 1 row instead of getting all the data that you want to show. 这样做将导致多个firebase调用仅获取1行数据,而不是获取要显示的所有数据。
The solution of this is to do all your firebase logic in your main activity and pass the data to the adapter to set the values. 解决方案是在主要活动中执行所有Firebase逻辑,然后将数据传递给适配器以设置值。
To solve this with a more cleaner approach, pass your Array as a parameter in your Adapter Constructor, delete the addAll
method and do this. 要使用更addAll
方法解决此问题,请将Array作为参数传递给Adapter Constructor,删除addAll
方法并执行此操作。
public PostAdapter(Context c, List<Post> mPost) {
this.mPost = mPost
mContext=c;
}
Then as I said, delete all the firebase code from your onBindViewHolder
and place it in your MainActivity
然后,正如我所说的,从onBindViewHolder
删除所有onBindViewHolder
代码,并将其放在MainActivity
With the constructor changed of your Adapter, you should now use your data fetched from firebase like this to work with your adapter. 更改适配器的构造函数后,您现在应该使用从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) {
}
});
If you want to notify your adapter about any change. 如果您想将任何更改通知您的适配器。 Just make a global declaration of the adapter like 只需像这样对适配器进行全局声明
private PostAdapter adapter;
and then just use 然后就用
adapter.notifySetDataChanged();
Make sure the instance has been executed at least once. 确保实例至少已执行一次。
mAdapter = new PostAdapter(MainActivity.this,userModels);
Firebase has released firebaseRecyclerViewAdapter class. Firebase已发布firebaseRecyclerViewAdapter类。 This will do a lot of the work for you. 这将为您完成很多工作。
the adapter takes 4 input arguments: 适配器采用4个输入参数:
the populateViewHolder method is all that will be required 仅需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());
}
};
Then set the adapter: 然后设置适配器:
recycler.setAdapter(mAdapter);
More info on this Firebase RecyclerView Adapter 关于此Firebase RecyclerView适配器的更多信息
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.