Im trying to implement a RecyclerView in my app. This is my Adapter class:
public class AdapterItemsList extends RecyclerView.Adapter<AdapterItemsList.ViewHolderItems>
{
private ArrayList<CItem> items;
public AdapterItemsList(ArrayList<CItem> items)
{
this.items = items;
}
@NonNull
@Override
public ViewHolderItems onCreateViewHolder(@NonNull ViewGroup parent, int viewType)
{
View view = LayoutInflater.from(parent.getContext())
.inflate(R.layout.item_counter, null, false);
return new ViewHolderItems(view);
}
@Override
public void onBindViewHolder(@NonNull final ViewHolderItems holder, final int position)
{
holder.asignarDatos(items.get(holder.getAdapterPosition()));
holder.itemView.setOnLongClickListener(new View.OnLongClickListener() {
@Override
public boolean onLongClick(View view) {
//deleteSelectedItem() method gonna be here
Toast.makeText(view.getContext(), String.valueOf(holder.getAdapterPosition())
, Toast.LENGTH_SHORT).show();
return false;
}
});
holder.counterAdd.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
Integer auxInteger = Integer.parseInt(holder.itemNumber.getText().toString());
auxInteger += 1;
holder.itemNumber.setText(auxInteger.toString());
items.get(holder.getAdapterPosition()).setObjectNumber(Integer.parseInt(holder.itemNumber.getText().toString()));
}
});
holder.counterSubtract.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
Integer auxInteger = Integer.parseInt(holder.itemNumber.getText().toString());
if (auxInteger > 0)
{
auxInteger -= 1;
holder.itemNumber.setText(auxInteger.toString());
items.get(holder.getAdapterPosition()).setObjectNumber(Integer.parseInt(holder.itemNumber.getText().toString()));
}
}
});
}
@Override
public int getItemCount()
{
return items.size();
}
public class ViewHolderItems extends RecyclerView.ViewHolder
{
TextView itemName;
TextView itemNumber;
Button counterAdd;
Button counterSubtract;
public ViewHolderItems(View itemView)
{
super(itemView);
itemName = (TextView) itemView.findViewById(R.id.textViewItemCounterName);
itemNumber = (TextView) itemView.findViewById(R.id.textViewItemCounterNumber);
counterAdd = (Button) itemView.findViewById(R.id.buttonItemCounterAdd);
counterSubtract = (Button) itemView.findViewById(R.id.buttonItemCounterSubtract);
}
public void asignarDatos(CItem item)
{
itemName.setText(item.getObjectName());
itemNumber.setText(item.getObjectNumber().toString());
}
}
}
The code that "creates" the adapter:
private void CreateAdapter() {
recyclerViewItems.setAdapter(null);
items.clear();
//I dont post the code, but this just gets data from a SQLite database and populate "items".
LoadClientsList();
final AdapterItemsList adapter = new AdapterItemsList(items);
recyclerViewItems.setAdapter(adapter);
}
As you can see, I never use "implements View.OnLongClickListener" or something like that, but I just set the OnClickListener inside onBindViewHolder. Now there is a "Toast" inside (which appears just fine when I test the app), but later on, there should be my "delete item" dialog, that gonna give the user the change to Accept or Cancel (an usual dialog). If the user press "accept" then I gonna remove the item from the list.
I gonna admit, Im not an Android or Java Ninja, so I know there are horrendous mistakes probably. But the thing is, the app is working by now (the Toast appears correctlywhen I long-press an item), but the fact that I never use "implements", while I see everyone does it in StackOverflow questions related to RecyclerViews and Adapters, make me think Im making (several) serious mistakes.
I could admit since Im not a master at Java fundamentals (some years working with COBOL already that I remember almost NULL of OOP), I don't see where my mistakes are, but still, any help will be much appreciated.
Thanks in regard!
UPDATE: Ok I was changing my code and now its like follows:
public class AdapterItemsList extends RecyclerView.Adapter<AdapterItemsList.ViewHolderItems> implements View.OnClickListener { private ArrayList<CItem> items; /* Added this */ private View.OnClickListener listener; public AdapterItemsList(ArrayList<CItem> items) { this.items = items; } @NonNull @Override public ViewHolderItems onCreateViewHolder(@NonNull ViewGroup parent, int viewType) { View view = LayoutInflater.from(parent.getContext()) .inflate(R.layout.item_counter, null, false); /* Added this */ view.setOnClickListener(this); return new ViewHolderItems(view); } @Override public void onBindViewHolder(@NonNull final ViewHolderItems holder, final int position) { holder.asignarDatos(items.get(holder.getAdapterPosition())); holder.counterAdd.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { Integer auxInteger = Integer.parseInt(holder.itemNumber.getText().toString()); auxInteger += 1; holder.itemNumber.setText(auxInteger.toString()); items.get(holder.getAdapterPosition()).setObjectNumber(Integer.parseInt(holder.itemNumber.getText().toString())); } }); holder.counterSubtract.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { Integer auxInteger = Integer.parseInt(holder.itemNumber.getText().toString()); if (auxInteger > 0) { auxInteger -= 1; holder.itemNumber.setText(auxInteger.toString()); items.get(holder.getAdapterPosition()).setObjectNumber(Integer.parseInt(holder.itemNumber.getText().toString())); } } }); } @Override public int getItemCount() { [...] } /* Added this */ public void setOnClickListener(View.OnClickListener listener) { this.listener = listener; } /* Added this */ @Override public void onClick(View view) { if (listener != null) { listener.onClick(view); } } public class ViewHolderItems extends RecyclerView.ViewHolder { [...] } }
Code where I create the adapter:
private void CreateAdapter() { recyclerViewItems.setAdapter(null); items.clear(); LoadClientsList(); final AdapterItemsList adapter = new AdapterItemsList(items); /* Added this */ adapter.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { Toast.makeText(getApplicationContext(), String.valueOf(recyclerViewItems.getChildAdapterPosition(view)), Toast.LENGTH_SHORT).show(); } }); recyclerViewItems.setAdapter(adapter); }
The "recyclerViewItems.getChildAdapterPosition(view)" finally solves my problem (didn't mentioned before, but it was the reason why I put the "setOnClick..." inside the onBindViewHolder method, just because I needed the position of the pressed item and I couldnt figure out how on earth to access it). So now I set the listener when I create the adapter instead of when Binding the View holder, which I guess it's better. Still, I didnt change the "holder.counterAdd.setOnClickListener" and "holder.counterSubtract.setOnClickListener" lines, since I think they must be inside the onBindViewHolder method, but I guess Im still wrong on that.