我曾尝试从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());
}
}
答案 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个输入参数:
仅需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);
的更多信息