简体   繁体   中英

Hide a row in Android RecycleView

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

I am trying to hide a specific row inside a RecycleView. I am currently able to display all users in the Firebase Realtime Database. I want to add one constraint in order to hide the row of the current user logged in. I am unsure of how to hide a specific row if anyone can help me please. a lot of people online are saying that it is not possible. Can anyone please help me?

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();
        }
    }
}

Try to hide all views or parent from Viewholder layout xml. You should hide entire viewholder or each view

Entire viewholder:

itemView.setVisibility(View.GONE);

or each element:

view.setVisibility(View.GONE);

When you are using the Firebase-UI library, you need to pass to the setQuery() method a Query object. Looking at your code, I see that you are passing a simple DatabaseReference object rather than a Query. That object actually contains all User objects that exist under the "User" node. This means that your adapter will always create a view, for each and every user. Even if you create an if statement inside your onBindViewHolder() method, that checks whether the email of the user is the same as the one of the logged-in user, you'll end up having an empty view.

What you should do instead, is to create a query that generates only the users that you are interested in. This means you'll have to ask Firebase Realtime Database to filter the users and get all of them, except one. Unfortunately, there is no such negation (!=) query. Firebase can't perform this filtering. So, FirebaseRecyclerAdapter won't help you with this.

To solve this problem, you'll have to read User objects from that location, and manually filter them on the client. So you should get a list of all users, and then simply remove the one that you don't need. You can then build an Adapter with that list, and display the users in your RecyclerView. It's not ideal, as you'll lose the features of the Firebase-UI library but it will do the trick.

However, if you consider at some point in time to try using Cloud Firestore , which I personally recommend, this problem has a really simple solution. There is a not equal (!=) method that does the exact thing you are looking for:

Use the not equal (!=) operator to return documents where the given field exists and does not match the comparison value.

And in code might look like this:

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM