javaandroidfirebasefirebase-realtime-databasesectionedrecyclerviewadapter

Android Firebase RecyclerView Adapter Remove Views


I am facing a Firebase RecyclerView problem where I cannot remove unwanted CardViews from my RecyclerViews. In my code I check the city's name and the guide's chosen city to match them. It populates guide's details only if the guide's city matches the picked city, but it also shows empty cardview with default layout.

guideDataRef = FirebaseDatabase.getInstance().getReference().child("Guides");

public void recycler() {
        super.onStart();

        try {
            //Guide RecyclerView
            Query guideQuery = guideDataRef.orderByKey();
            guideQuery.keepSynced(true);

            FirebaseRecyclerOptions guideOptions =
                    new FirebaseRecyclerOptions.Builder<UserModelClass>().setQuery(guideQuery, UserModelClass.class).build();

            guideAdapter = new FirebaseRecyclerAdapter<UserModelClass, guideViewHolder>(guideOptions) {


                @Override
                protected void onBindViewHolder(@NonNull guideViewHolder holder, final int position, @NonNull final UserModelClass model) {

                    String pickedcity = model.getPickedCity();
                    String postname = (String) cityName.getText();

                    if(pickedcity.equals(postname)) {

                        final String guide_key= getRef(position).getKey();

                        holder.setGuideName(model.getName());
                        holder.setGuideSurname(model.getSurName());
                        holder.setGuideImage(getApplicationContext(), model.getPhotoURL());
                       // holder.mView.setVisibility(View.VISIBLE);

                        //Guide Click listener
                        holder.mView.setOnClickListener(new View.OnClickListener() {
                            @Override
                            public void onClick(View v) {

                                Intent guideHireIntent = new Intent(getApplication(), GuideHireActivity.class);
                                guideHireIntent.putExtra("guide_id", guide_key);
                                finish();
                                startActivity(guideHireIntent);

                            }
                        });

                    }

                }

                @NonNull
                @Override
                public guideViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
                    View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.item_layout_guides, parent, false);
                    return new guideViewHolder(view);
                }

                @Override
                public void onError(DatabaseError e){
                    Toast.makeText(getApplicationContext(), "Error by stopping ", Toast.LENGTH_SHORT).show();
                }

                @Override
                public int getItemCount() {
                    return super.getItemCount();
                }

                @Override
                public void onDataChanged() {
                    super.onDataChanged();
                    notifyDataSetChanged();
                }
            };

            guideAdapter.notifyDataSetChanged();
            guideRecyclerView.setAdapter(guideAdapter);
            guideAdapter.startListening();


        } catch (DatabaseException e) {

            Toast.makeText(this, "Error", Toast.LENGTH_SHORT).show();

        }

    }

enter image description here
enter image description here

I can change the adapter visibility to gone if it does not match with the requirements but the problem is that after making it's visibility gone it is still there holding the place (but invisible - there's still an empty space). How can I avoid populating an item from the recycler view completely, instead of making it invisible if the requirements do not match?


Solution

  • You're not showing what guideDataRef is in your code, so I'm assuming that it's just aDatabaseReference object for everything beneath a \Guides node.

    If you're doing that, you're going to get a call for onBindViewHolder for every child at that particular location. This means that you're going to be asked to make a view for every child. You cannot choose whether or not a view will appear for that item.

    It looks like you're assuming that your if statement in onBindViewHolder method will skip over those items. But what's actually happening is that you're simply allowing an empty view to occupy that spot in the list.

    Instead, you should come up with a query that generates only the items of interest to your list. This means you'll have to tell Firebase to filter for children that meet your criteria.

    You can also read the entire contents of the location, manually filter out the items you don't want, and build a list of items you do want. You can then build an custom adapter with that list, and it can then become the input to a ListView or even better to a RecyclerView.