0

Hi everyone I have a question that I can't figure out about how do I know what element of the array I'm clicking in the shopping cart. So I have a shopping cart with 5 items. Each item is an object that contains (Name, Surname, Price, Key(is the key of the object inside the firebase realtime database)) and for each object, I have an ImageButton that I can click to remove that item from the cart. My problem is that I can't understand how I can know what item I'm clicking in that specific moment, because when I delete the idem I have to pass it the key and to get the key I have to know the item position in the array.

I'm attaching the Code so you can understand better. I'm new to Android and it's the first time that I'm doing this.

Thank you so much in advance.

Code :

public class CartActivity extends AppCompatActivity implements  OnRemoveItemClickListener{

    private TextView total;
    private ImageButton removeFromCart;
    private Button pay;
    private RecyclerView mResultList2;
    private DatabaseReference mUserDatabase;
    int i=0;
    int Totalprice=0;
    OnRemoveItemClickListener item;
    private RecyclerView.Adapter adapter;
    private ArrayList<Users_get> array_data = new ArrayList<>();
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_cart);
        mUserDatabase = FirebaseDatabase.getInstance().getReference("Cart");

        total          = findViewById(R.id.TotalPrice);
        removeFromCart = findViewById(R.id.removeFromCart);
        mResultList2    = findViewById(R.id.cartList);
        pay            = findViewById(R.id.pay);

        mResultList2.setHasFixedSize(true);
        mResultList2.setLayoutManager(new LinearLayoutManager(this));


        // Attach a listener to read the data at our posts reference
        mUserDatabase.addValueEventListener(new ValueEventListener() {


            @Override
            public void onDataChange(DataSnapshot dataSnapshot) {
                for(DataSnapshot childSnapshot : dataSnapshot.getChildren()) {
                    Users_get post = childSnapshot.getValue(Users_get.class);
                    array_data.add(new Users_get(post.getName(),post.getSurname(),post.getPrice(),childSnapshot.getKey()));
                    getTotalPrice(post.getPrice());
                    adapter = new UsersAdapter(array_data,item);
                    mResultList2.setAdapter(adapter);
                }
            }



            @Override
            public void onCancelled(DatabaseError databaseError) {
                System.out.println("The read failed: " + databaseError.getCode());
            }

        });

    }

    public int getTotalPrice(Long price){
        if (array_data != null) {

                Totalprice+=price;

        }System.out.println("total Price is :"+Totalprice);
        return Totalprice;
    }


    @Override
    public void onRemoveItemClicked(final int position) {
        removeFromCart.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                FirebaseDatabase.getInstance().getReference("Cart").child(array_data.get(position).getKey()).removeValue();
            }
        });
        adapter.notifyItemRemoved(position);
    }
}

JSON file :

    {
  "Cart" : {
    "-M0U3UXq2ZA00Jq5o9as" : {
      "name" : "Alex",
      "price" : 120,
      "surname" : "Kyto"
    },
    "-M0WlUbQHj1hdH40uWVF" : {
      "name" : "Alex",
      "price" : 120,
      "surname" : "Kyto"
    },
    "-M0WxZhI98Xb1s9Xy5HV" : {
      "name" : "Alex",
      "price" : 120,
      "surname" : "Kyto"
    },
    "-M0X00Zr64RocyQHhoFB" : {
      "name" : "Alex",
      "price" : 120,
      "surname" : "Kyto"
    }
  },
  "Users" : {
    "01" : {
      "Name" : "Alex",
      "Price" : 120,
      "Surname" : "Kyto"
    },
    "02" : {
      "Name" : "Alex",
      "Price" : 200,
      "Surname" : "Pablo"
    }
  }
}

USER ADAPTER :

     package com.example.ipill;

import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageButton;
import android.widget.TextView;

import androidx.annotation.NonNull;
import androidx.recyclerview.widget.RecyclerView;

import java.util.ArrayList;


public class UsersAdapter extends RecyclerView.Adapter<UsersAdapter.ViewHolder> {

    private ArrayList<Users_get> cities;
    public int position;
    private OnRemoveItemClickListener mListener;
    public UsersAdapter(ArrayList<Users_get> cities,OnRemoveItemClickListener listener) {
        this.cities = cities;
        this.mListener = listener;
    }

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

    @Override
    public void onBindViewHolder(@NonNull ViewHolder holder, final int position) {
        final Users_get city = cities.get(position);
        holder.name.setText(city.getName());
        holder.surname.setText(city.getSurname());
        holder.price.setText(Long.toString(city.getPrice()));

    }

    @Override
    public int getItemCount() {
        if (cities != null) {
            return cities.size();
        } else {
            return 0;
        }
    }

    public  class ViewHolder extends RecyclerView.ViewHolder {
        public final View view;
        public final TextView name;
        public final TextView surname;
        public final TextView price;
        public final ImageButton removee;


        public ViewHolder(View view) {
            super(view);
            this.view = view;
            name = view.findViewById(R.id.name2);
            surname = view.findViewById(R.id.Surname2);
            price = view.findViewById(R.id.Price2);
            removee = view.findViewById(R.id.removeFromCart);

            removee.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    mListener.onRemoveItemClicked(ViewHolder.this.getAdapterPosition());
                }
            });

        }
    }
}

Error : java.lang.NullPointerException: Attempt to invoke interface method 'void com.example.ipill.OnRemoveItemClickListener.onRemoveItemClicked(int)' on a null object reference

Since the Image button is create when the objects inside the recycle view are created.

enter image description here

Alex97
  • 401
  • 1
  • 8
  • 21
  • Share UsersAdapter code please – Kishan Maurya Feb 20 '20 at 16:27
  • 1
    I updated the question with the UserAdapter – Alex97 Feb 20 '20 at 16:29
  • Please confirm one thing: How you are going to delete the item. Like when user press any item on list then you you want to save that position and when user clicks on ImageButton then you will perform delete action. Ideally, for each item in the adapter, there should be a corresponding delete button or checkbox something. – Kishan Maurya Feb 20 '20 at 16:39
  • First step: I click on the Shopping Cart and the app opens the CartActivity. Second step: The app downloads the data from firebase realtime database and displays each object inside the recycle view with an image button for each object. If I click the Image button I want to remove the item from the database and from the recycle view so the shopping cart has -1 item. This is how I want to do it. – Alex97 Feb 20 '20 at 16:44

2 Answers2

2

I have changed the required thing, like passing listener from activity to adapter then callback from adapter,

Create 1 interface,

public IItemClick{
 public void onItemClick (String key, int position)
}

Activity Class

public class CartActivity extends AppCompatActivity implements IItemClick {

     // change  
    public void onDataChange(DataSnapshot dataSnapshot) {
                for(DataSnapshot childSnapshot : dataSnapshot.getChildren()) {
                    Users_get post = childSnapshot.getValue(Users_get.class);
                    array_data.add(new Users_get(post.getName(),post.getSurname(),post.getPrice(),childSnapshot.getKey()));
                    adapter = new UsersAdapter(array_data, this);
                    mResultList2.setAdapter(adapter);
                }
            }


                override public void onItemClick(String key, int position){
                 // perform your delete operation from firebase here
                 // after delete  
                adapter.notifyItemRemoved(position)
                }

        }

Adapter Code

public class UsersAdapter extends RecyclerView.Adapter<UsersAdapter.ViewHolder> {

    private ArrayList<Users_get> cities;
    public int position;
    IItemClick listener;
    public UsersAdapter(ArrayList<Users_get> cities,IItemClick listener ) {
        this.cities = cities;
        this.listener = listener
    }

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

    @Override
    public void onBindViewHolder(@NonNull ViewHolder holder, int position) {
        Users_get city = cities.get(position);
        holder.name.setText(city.getName());
        holder.surname.setText(city.getSurname());
        holder.price.setText(Long.toString(city.getPrice()));
        holder.name.setOnClickListener(new View.OnClickListener(){
        @Override
        public void onClick(View v){
         listener.onItemClick(city.getKey(), position);
        }

    }

    @Override
    public int getItemCount() {
        if (cities != null) {
            return cities.size();
        } else {
            return 0;
        }
    }

    public static class ViewHolder extends RecyclerView.ViewHolder {
        public final View view;
        public final TextView name;
        public final TextView surname;
        public final TextView price;


        public ViewHolder(View view) {
            super(view);
            this.view = view;
            name = view.findViewById(R.id.name_text2);
            surname = view.findViewById(R.id.status_text2);
            price = view.findViewById(R.id.price2);
    }
}
Kishan Maurya
  • 3,356
  • 8
  • 21
  • I tried to do what you told me but I keep getting this error : Attempt to invoke interface method 'void com.example.ipill.OnRemoveItemClickListener.onRemoveItemClicked(int)' on a null object reference , I updated the code if you want to check it out. Thank you – Alex97 Feb 20 '20 at 18:10
  • 1
    use adapter = new UsersAdapter(array_data,this); not item – Kishan Maurya Feb 20 '20 at 18:15
  • If i use this then it gives me this error : change 2nd parameter of method UserAdapter from OnRemoveItemClickListener to ValueEventListener and if I do this everything you told me is not usable – Alex97 Feb 20 '20 at 18:20
  • 1
    adapter = new UsersAdapter(array_data,CartActivity.this); – Kishan Maurya Feb 20 '20 at 18:25
  • it worked but as I said previously I get the error : check the picture if you have time. Thank you – Alex97 Feb 20 '20 at 18:28
  • 1
    Why are you performing same action twice. First click on Adapter item and then click on activity. just do like @Override public void onRemoveItemClicked(final int position) { FirebaseDatabase.getInstance().getReference("Cart").child(array_data.get(position).getKey()).removeValue(); adapter.notifyItemRemoved(position); } – Kishan Maurya Feb 20 '20 at 18:41
  • 1
    Let us [continue this discussion in chat](https://chat.stackoverflow.com/rooms/208206/discussion-between-kishan-maurya-and-alex97). – Kishan Maurya Feb 20 '20 at 18:44
1

Please follow step by step procedure:

1) I'm considering that you have the Image Button in your R.layout.list_layout_cart, now find that ImageButton by FindViewById() method in your ViewHolder class in UserAdapter (Here please keep the ViewHolder class non-static).

So here is your UserAdapter

public class UsersAdapter extends RecyclerView.Adapter<UsersAdapter.ViewHolder> {

private ArrayList<Users_get> cities;
public int position;

private OnRemoveItemClickListener mListener;

public UsersAdapter(ArrayList<Users_get> cities, OnRemoveItemClickListener listener) {
    this.cities = cities;

    this.mListener = listener;
}

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

@Override
public void onBindViewHolder(@NonNull ViewHolder holder, int position) {
    Users_get city = cities.get(position);
    holder.name.setText(city.getName());
    holder.surname.setText(city.getSurname());
    holder.price.setText(Long.toString(city.getPrice()));

}

@Override
public int getItemCount() {
    if (cities != null) {
        return cities.size();
    } else {
        return 0;
    }
}

public class ViewHolder extends RecyclerView.ViewHolder {
    public final View view;
    public final TextView name;
    public final TextView surname;
    public final TextView price;

    public Button mImageButton;


    public ViewHolder(View view) {
        super(view);
        this.view = view;
        name = view.findViewById(R.id.name_text2);
        surname = view.findViewById(R.id.status_text2);
        price = view.findViewById(R.id.price2);

        mImageButton = view.findViewById(R.id.btn_img_remove);

        mImageButton.setOnClickListener(v -> {
            if(mListener != null) {
                 mListener.onRemoveItemClicked(getAdapterPosition()));
             }
        });

    }
}
}

2) Create an Interface like this

public interface OnRemoveItemClickListener{
    void onRemoveItemClicked(int position);
}

3) Now Just Implement the Interface in your Activity and handle the item removal from Array in your Activity

halfer
  • 19,824
  • 17
  • 99
  • 186
  • Hello I tried to modify as you told me but it keeps telling me :Attempt to invoke interface method 'void com.example.ipill.OnRemoveItemClickListener.onRemoveItemClicked(int)' on a null object reference , I updated the code so you can see the actual code right now – Alex97 Feb 20 '20 at 18:09
  • Change the CartActivity Code like follows : adapter = new UserAdapter(array_items, this); – Ankush Yerawar Feb 21 '20 at 04:15