Android使用FirestoreRecyclerAdapter如何移除RecyclerView无内容空项
问题场景
我正在开发一个展示当前用户已关注账号发布帖子的Activity,通过如下方式设置查询指向当前用户的关注列表,在onBindViewHolder中将获取到的信息加载到CardView中:
FirestoreRecyclerOptions<GetInfoPost> options = new FirestoreRecyclerOptions.Builder<GetInfoPost>() .setQuery(FirebaseFirestore.getInstance().collection("following").document(fAuth.getCurrentUser().getUid()).collection("/userFollowing").limit(1000), GetInfoPost.class) .build(); FirestoreRecyclerAdapter<GetInfoPost, FindFriendsViewHolder> firestoreRecyclerAdapter =new FirestoreRecyclerAdapter<GetInfoPost, FindFriendsViewHolder>(options) { @Override protected void onBindViewHolder(@NonNull FindFriendsViewHolder findFriendsViewHolder, int i, @NonNull GetInfoPost getInfoPost) { final String listUserId = getSnapshots().getSnapshot(i).getId(); FirebaseFirestore rootRef = FirebaseFirestore.getInstance(); Query userPostsRef = rootRef.collection("post").document(listUserId).collection("userPosts").limit(1); userPostsRef.get().addOnCompleteListener(new OnCompleteListener<QuerySnapshot>() { @Override public void onComplete(@NonNull Task<QuerySnapshot> task) { if (task.isSuccessful()) { String postID = ""; for (QueryDocumentSnapshot document : task.getResult()) { postID = document.getId(); } String finalPostID = postID; if(finalPostID.equals("")){ return; } FirebaseFirestore.getInstance().collection("likes").document(finalPostID).collection("postLikes").get().addOnCompleteListener(new OnCompleteListener<QuerySnapshot>() { @Override public void onComplete(@NonNull Task<QuerySnapshot> task) { if(task.isSuccessful()){ int count = 0; for (DocumentSnapshot document : task.getResult()) { count++; } Log.d("TAG", count + ""); findFriendsViewHolder.txtLikenmb.setText(count + ""); } } });
目前功能基本正常,仅存在一个问题:当我关注的用户没有发布过帖子时,RecyclerView仍会生成对应空条目,我目前通过如下判空逻辑避免应用崩溃:
if(finalPostID.equals("")){ return; }
但我希望完全不展示这类空帖子,效果如下图:
我之前查阅过同类问题,相关解决方案都基于ArrayList这类本地数据集实现,不适用于我当前的FirestoreRecyclerAdapter场景,请问有什么方法可以从RecyclerView中删除这类无效空项?
解决方案
方案1:服务端数据源过滤(最推荐)
在用户的账号文档中新增hasPost布尔类型字段,用户首次发布帖子时将字段设为true,删除所有帖子时改回false。查询关注列表时直接增加过滤条件,从数据源层面直接排除无帖子的用户:
.setQuery(FirebaseFirestore.getInstance().collection("following").document(fAuth.getCurrentUser().getUid()).collection("/userFollowing").whereEqualTo("hasPost",true).limit(1000), GetInfoPost.class)
该方案不需要客户端额外处理逻辑,不会产生多余的查询请求,性能最优、成本最低。
方案2:客户端动态隐藏空项(快速实现)
如果暂时无法修改服务端逻辑,可以在判空时直接将当前item的布局参数设置为不可见,完全隐藏空项:
if(finalPostID.equals("")){ RecyclerView.LayoutParams params = new RecyclerView.LayoutParams(0,0); params.setMargins(0,0,0,0); findFriendsViewHolder.itemView.setLayoutParams(params); findFriendsViewHolder.itemView.setVisibility(View.GONE); return; } // 有帖子的场景要恢复正常布局参数,避免复用时出现显示异常 RecyclerView.LayoutParams params = new RecyclerView.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT); // 替换为你原始布局的margin值 params.setMargins(0, Utils.dp2px(8),0,Utils.dp2px(8)); findFriendsViewHolder.itemView.setLayoutParams(params); findFriendsViewHolder.itemView.setVisibility(View.VISIBLE);
方案3:客户端维护过滤数据集
如果需要更规范的实现,可以自定义适配器继承FirestoreRecyclerAdapter,内部维护有效项的索引列表:
- 适配器内部定义存储有效索引的列表
private List<GetInfoPost> validItems = new ArrayList<>();
- 监听数据集变化,每次数据更新时遍历所有项,查询对应用户是否有帖子,筛选后更新有效列表并调用
notifyDataSetChanged()
该方案性能比前两种差,关注用户较多时会产生大量额外查询,仅小范围场景下适用。
内容的提问来源于stack exchange,提问作者Conta
相关产品推荐
相关产品推荐

