bateler8
bateler8

Reputation: 105

Remove RecyclerView Firebase Item Android Java

I've created a favourites page using a RecyclerView with data saved on firebase. I'm attempting to delete an item from both firebase and the recyclerview in realtime. I can remove the item using

dataSnapshot.child(countries.get(position).getId()).getRef().removeValue();
countries.remove(position);

However, I can't remove the last item, but it deletes in firebase. I've tried different combinations of

notifyDataSetChanged();
notifyItemRemoved(position);
notifyItemRangeChanged(position, countries.size());

But with no luck so far, I can't see where I'm going wrong.

Populating recyclerview

Public class FavouritesFragment extends Fragment {
    RecyclerView recyclerView;
    RecyclerView.LayoutManager layoutManager;
    RecyclerView.Adapter adapter;
    ArrayList<Country> countries;

    private FirebaseAuth firebaseAuth;
    private DatabaseReference databaseReference;

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
                             Bundle savedInstanceState) {

        final View view = inflater.inflate(R.layout.fragment_favourites, container, false);

        getActivity().setTitle("Favourites");

        firebaseAuth = FirebaseAuth.getInstance();
        databaseReference = FirebaseDatabase.getInstance().getReference();
        FirebaseUser user = firebaseAuth.getCurrentUser();
        String userID = user.getUid();
        databaseReference = databaseReference.child("users").child(userID).child("Favourites");

        recyclerView = view.findViewById(R.id.favourites_recycler);
        countries = new ArrayList<>();
        layoutManager = new LinearLayoutManager(getContext());
        recyclerView.setLayoutManager(layoutManager);

        addFavourites();

        return view;
    }

    public void addFavourites(){
        databaseReference.addValueEventListener(new ValueEventListener() {
            @Override
            public void onDataChange(@NonNull DataSnapshot dataSnapshot) {
                for (DataSnapshot ds: dataSnapshot.getChildren()){

                    Country c = ds.getValue(Country.class);
                    countries.add(c);

                }

                adapter = new FavouritesAdapter(countries);
                recyclerView.setAdapter(adapter);

            }

            @Override
            public void onCancelled(@NonNull DatabaseError databaseError) {

            }
        });
    }

}

Deleting from RecyclerView in adapter class

public class FavouritesAdapter extends RecyclerView.Adapter<FavouritesAdapter.MyViewHolder>{
    ArrayList<Country> countries;
    private View view;
    ImageBindingAdapter imageBindingAdapter = new ImageBindingAdapter();
    RecyclerView recyclerView;
    private int position;

    private FirebaseDatabase firebaseDatabase;
    private FirebaseAuth firebaseAuth;
    private DatabaseReference databaseReference;

    public FavouritesAdapter(ArrayList<Country> countries1){
        countries = countries1;
    }

    @NonNull
    @Override
    public FavouritesAdapter.MyViewHolder onCreateViewHolder(@NonNull ViewGroup viewGroup, int i) {

        view = LayoutInflater.from(viewGroup.getContext()).inflate(R.layout.favourites, viewGroup, false);
        recyclerView = view.findViewById(R.id.favourites_recycler);

        firebaseAuth = FirebaseAuth.getInstance();
        firebaseDatabase = FirebaseDatabase.getInstance();
        databaseReference = firebaseDatabase.getReference();

        FirebaseUser user = firebaseAuth.getCurrentUser();
        String userID = user.getUid();
        databaseReference = databaseReference.child("users").child(userID).child("Favourites");

        return new FavouritesAdapter.MyViewHolder(view);
    }

    @Override
    public void onBindViewHolder(@NonNull final FavouritesAdapter.MyViewHolder myViewHolder, final int i) {
        myViewHolder.name.setText(countries.get(i).getName());
        myViewHolder.snippet.setText(countries.get(i).getSnippet());

        myViewHolder.popUp.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                PopupMenu popup = new PopupMenu(view.getContext(), view);
                MenuInflater inflater = popup.getMenuInflater();
                inflater.inflate(R.menu.popup_menu, popup.getMenu());
                popup.show();

                popup.setOnMenuItemClickListener(new PopupMenu.OnMenuItemClickListener() {
                    @Override
                    public boolean onMenuItemClick(MenuItem item) {
                        switch (item.getItemId()) {
                            case R.id.add_to_favs:

                                deleteFavourite();

                                break;
                            default:
                                return false;
                        }
                        return true;
                    }
                });

            }
        });

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

    class MyViewHolder extends RecyclerView.ViewHolder  {
        public TextView name;
        public ImageView popUp;

        public MyViewHolder(View itemView) {
            super(itemView);

            name = itemView.findViewById(R.id.cityName);
            popUp = itemView.findViewById(R.id.dotsPopUp);

        }

    }

    public void deleteFavourite(){
        databaseReference.addValueEventListener(new ValueEventListener() {
            @Override
            public void onDataChange(@NonNull DataSnapshot dataSnapshot) {
                String id = countries.get(position).getId();

                if(dataSnapshot.exists() && dataSnapshot.child(id).exists()){
                    dataSnapshot.child(countries.get(position).getId()).getRef().removeValue();
                    countries.remove(position);
//                    notifyDataSetChanged();
//                                            notifyItemRemoved(position);
//                                            notifyItemRangeChanged(position, countries.size());
                }

            }

            @Override
            public void onCancelled(@NonNull DatabaseError databaseError) {

            }

        });    }



}

Upvotes: 1

Views: 105

Answers (2)

Zain
Zain

Reputation: 40908

In your adapter you didn't set the position to the position of the item you need to delete. So when the user hits the delete item in the popUp menu, you call deleteFavourite();, but you need to set the class field position before calling deleteFavourite().

So, in onBindViewHolder, you need to assign the value of the second parameter to the position, and it's better to pass it to deleteFavourite() method as a paraemter like deleteFavourite(position):

@Override
public void onBindViewHolder(@NonNull final FavouritesAdapter.MyViewHolder myViewHolder, final int pos) {

            .... 

            popup.setOnMenuItemClickListener(new PopupMenu.OnMenuItemClickListener() {
                @Override
                public boolean onMenuItemClick(MenuItem item) {
                    switch (item.getItemId()) {
                        case R.id.add_to_favs:

                            deleteFavourite(pos);

                            break;
                        default:
                            return false;
                    }
                    return true;
                }
            });

Then change your deleteFavourite to accept the new parameter, and notifyItemRemoved(position);

public void deleteFavourite(int pos){
    databaseReference.addValueEventListener(new ValueEventListener() {
        @Override
        public void onDataChange(@NonNull DataSnapshot dataSnapshot) {
            String id = countries.get(pos).getId();

            if(dataSnapshot.exists() && dataSnapshot.child(id).exists()){
                dataSnapshot.child(countries.get(pos).getId()).getRef().removeValue();
                countries.remove(pos);
                notifyItemRemoved(pos);
            }

        }

        @Override
        public void onCancelled(@NonNull DatabaseError databaseError) {

        }

    });    
}

Upvotes: 1

Hasan Bou Taam
Hasan Bou Taam

Reputation: 4035

Do this to remove object from list, in deleteFavourite() function:

..........


           if(dataSnapshot.exists() && dataSnapshot.child(id).exists()){
                dataSnapshot.child(countries.get(position).getId()).getRef().removeValue();

                countries.remove(countries.get(position));
                notifyDataSetChanged();


            }

..............

Upvotes: 0

Related Questions