【问题标题】:Hide a row in Android RecycleView在 Android RecyclerView 中隐藏一行
【发布时间】:2020-11-05 20:07:28
【问题描述】:

The image below is the JSON database which contains user objects.

我试图隐藏 RecycleView 中的特定行。我目前能够显示 Firebase 实时数据库中的所有用户。我想添加一个约束以隐藏当前登录用户的行。如果有人可以帮助我,我不确定如何隐藏特定行。网上很多人都说不可能。谁能帮帮我?

package com.example.bodify;

import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Toast;

import androidx.annotation.NonNull;
import androidx.appcompat.app.AppCompatActivity;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;
import com.example.bodify.Models.User;
import com.firebase.ui.database.FirebaseRecyclerAdapter;
import com.firebase.ui.database.FirebaseRecyclerOptions;
import com.google.firebase.auth.FirebaseAuth;
import com.google.firebase.auth.FirebaseUser;
import com.google.firebase.database.DataSnapshot;
import com.google.firebase.database.DatabaseError;
import com.google.firebase.database.DatabaseReference;
import com.google.firebase.database.FirebaseDatabase;
import com.google.firebase.database.Query;
import com.google.firebase.database.ValueEventListener;

import java.util.ArrayList;

public class ViewAllUsers extends AppCompatActivity{
    private RecyclerView rv;
    private FirebaseRecyclerOptions<User> userFirebaseRecyclerOptions;
    private FirebaseRecyclerAdapter<User,UserHolder> adapter;
    private FirebaseAuth mAuth = FirebaseAuth.getInstance();
    private FirebaseUser firebaseUser = mAuth.getCurrentUser();
    private ArrayList<User> users;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_view_all_users);
        getAllUsers();
        rv = findViewById(R.id.recyclerView);
        rv.setHasFixedSize(true);
        LinearLayoutManager linearLayoutManager = new LinearLayoutManager(getApplicationContext());
        rv.setLayoutManager(linearLayoutManager);
        DatabaseReference ref = FirebaseDatabase.getInstance().getReference().child("User");
        userFirebaseRecyclerOptions = new FirebaseRecyclerOptions.Builder<User>().setQuery(ref,User.class).build();
        adapter = new FirebaseRecyclerAdapter<User,UserHolder>(userFirebaseRecyclerOptions) {

            @Override
            protected void onBindViewHolder(@NonNull UserHolder holder, int position, @NonNull User model) {
                //no matter what if I add a statement in here to avoid current user it will end up coming as a blank view
                holder.setUserName(model.getUserName());
                holder.setEmailAddress(model.getEmail());
                holder.setImage(model.getmImageUrl());
            }
            @NonNull
            @Override
            public UserHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
                View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.user_item,parent,false);
                return new UserHolder(view);
            }


        };
        adapter.startListening();
        rv.setAdapter(adapter);
    }

    //steps
    //step 1. read all User Objects
    //Step 2. manually filter them
    //get a arraylist of all the users and simply remove the ones you dont want
    public void getAllUsers() {
        users = new ArrayList<>();
        DatabaseReference databaseReference = FirebaseDatabase.getInstance().getReference("User");
        databaseReference.addValueEventListener(new ValueEventListener() {
            @Override
            public void onDataChange(@NonNull DataSnapshot snapshot) {
                for (DataSnapshot userSnapshot : snapshot.getChildren()) {
                    User user = userSnapshot.getValue(User.class);
                    users.add(user);
                    for (int i = 0; i < users.size(); i++) {
                        if (users.get(i).getEmail().equalsIgnoreCase(firebaseUser.getEmail())) {
                            users.remove(i);
                    }
                }
                }
            }

            @Override
            public void onCancelled(@NonNull DatabaseError error) {
                Toast.makeText(ViewAllUsers.this,"Error Occurred: " + error.getMessage(),Toast.LENGTH_SHORT).show();
            }
        });
    }


            @Override
    protected void onStart() {
        super.onStart();
        if(adapter != null) {
            adapter.startListening();
        }
    }
    @Override
    protected void onStop() {
        super.onStop();
        if(adapter != null) {
            adapter.stopListening();
            super.onStop();
        }
    }
    @Override
    protected void onResume() {
        super.onResume();
        if(adapter != null) {
            adapter.startListening();
        }
    }
}

【问题讨论】:

  • 一个可能的解决方案是创建一个查询,但我是新手,任何人都知道如何处理这个
  • 想要隐藏哪些元素?你能提供一个具体的例子吗?还请编辑您的问题,将您的数据库结构添加为 JSON 文件或至少是屏幕截图。请回复@AlexMamo
  • @AlexMamo 我在上面添加了一个超链接到我的 JSON 数据库。我想在回收视图中显示所有用户,除了我不想显示当前用户登录到 auth 表的行。目前我的活动显示了数据库中的所有用户,但我想对此进行限制。注意我只在回收视图中使用图像用户名和电子邮件,但这不应该有所作为

标签: java android firebase firebase-realtime-database android-recyclerview


【解决方案1】:

当您使用 Firebase-UI 库时,您需要向 setQuery() 方法传递一个 Query 对象。查看您的代码,我看到您传递的是一个简单的 DatabaseReference 对象而不是一个查询。该对象实际上包含存在于“用户”节点下的 所有 用户对象。这意味着您的适配器将始终为每个用户创建一个视图。即使您在 onBindViewHolder() 方法中创建一个 if 语句来检查用户的电子邮件是否与登录用户的电子邮件相同,您最终也会得到一个空视图。

您应该做的是创建一个仅生成您感兴趣的用户的查询。这意味着您必须向 Firebase 实时数据库询问用户 filter 并获取所有用户,除了一个.不幸的是,没有这样的否定 (!=) 查询。 Firebase 无法执行此过滤。因此,FirebaseRecyclerAdapter 无法帮助您解决此问题。

要解决此问题,您必须从该位置读取用户对象,并在客户端上手动过滤它们。因此,您应该获取所有用户的列表,然后简单地删除不需要的用户。然后,您可以使用该列表构建一个适配器,并在您的 RecyclerView 中显示用户。这并不理想,因为您将失去 Firebase-UI 库的功能,但它可以解决问题。

但是,如果您考虑在某个时间点尝试使用我个人推荐的Cloud Firestore,那么这个问题有一个非常简单的解决方案。有一个 not equal (!=) 方法可以做你正在寻找的确切事情:

使用不等于 (!=) 运算符返回给定字段存在且与比较值不匹配的文档。

在代码中可能如下所示:

String email = FirebaseAuth.getInstance().getCurrentUser().getEmail();
FirebaseFirestore rootRef = FirebaseFirestore.getInstance();
CollectionReference usersRef = rootRef.collection("users");
Query query = usersRef.whereNotEqualTo("email", email);

【讨论】:

  • 嗨@AlexMamo 我现在将尝试实施您的建议。我今天会接受它,谢谢
  • 嘿@AlexMamo 我已经创建了一个只有我需要的用户的数组列表,我现在如何将此数组列表传递到回收视图中?
  • 当然可以,但首先,您应该为此创建一个 adapter。您不能简单地将列表传递给 RecyclerView。
  • 嗨 AlexMamo 我已经编辑了我上面的代码,如果你可以请看一下。我创建了一个 getAllUsers() 方法,它接收除当前用户之外的用户。我在创建时调用此方法,但我不确定下一步该做什么我有一个适配器,但不确定将这个数组列表传递到哪里?你能看看上面编辑过的代码吗?非常感谢
  • 您不再需要 Firebase-UI。所以你应该尝试在blog post 中实施解决方案。如果你在实现它时遇到困难,请使用它自己的MCVE 发布一个新问题,以便我和其他开发人员可以帮助你。
【解决方案2】:

尝试从 Viewholder 布局 xml 中隐藏所有视图或父视图。您应该隐藏整个视图或每个视图

整个视图:

itemView.setVisibility(View.GONE);

或每个元素:

view.setVisibility(View.GONE);

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-11-20
    相关资源
    最近更新 更多