问题
I am implementing multiple ViewHolders as suggested in this answer which uses an abstract bind()
. My current Adapter
and ViewHolder
looks likes:
// MyAdapter.java
{adapter code}
public static abstract class MyViewHolder extends RecyclerView.ViewHolder {
public MyViewHolder(View itemView) {
super(itemView);
}
protected abstract void bind(MyModel item);
}
// ViewHolder1.java
public class ViewHolder1 extends MyAdapter.MyViewHolder implements View.OnClickListener {
TextView textView;
public ViewHolder1(View itemView) {
super(itemView);
textView = itemView.findViewById(R.id.textView);
textView.setOnClickListener(this);
}
@Override
protected void bind(MyModel item) {
textView.setText(item.getText());
}
@Override
public void onClick(View view) {
//pass the current item position back to adapter
}
}
How can I pass the position of the clicked item from here back to the adapter. I don't want set onClickListener()
inside bind()
because it would then be called multiple times while my RecyclerView
is scrolled.
回答1:
Sorry for Kotlin, but you should be able to translate it to Java easily.
Add a click callback interface to your ViewHolder constructor. In the constructor (the init block in Kotlin) set a View.OnClickListener on the itemView.
class ViewHolder(
itemView: View,
clickCallback: (position: Int) -> Unit
) : RecyclerView.ViewHolder(itemView) {
init {
itemView.setOnClickListener {
clickCallback(layoutPosition)
}
}
}
When you create the ViewHolder, create an anonymous implementation of the click callback interface (in this case the clickCallback lambda) which provides the position of the clicked row. In this case, it uses the position to get the adapter item at the given position.
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder {
return ViewHolder(
itemView = LayoutInflater.from(parent.context)
.inflate(R.layout.action_list_item, parent, false),
clickCallback = { position ->
clickCallback(getItem(position))
}
)
}
class Adapter(private val clickCallback: (item: *YOUR_DATA_CLASS*) -> Unit)
回答2:
@Override
public void onBindViewHolder(@NonNull ViewHolder viewHolder, int i) {
viewHolder.btnPlus.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
// btn plus
}
});
viewHolder.btnMinus.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
// button minus
}
});
}
public class ViewHolder extends RecyclerView.ViewHolder
{
Button btnPlus, btnMinus;
public ViewHolder(@NonNull View itemView)
{
super(itemView);
btnPlus = itemView.findViewById(R.id.plusbutton);
btnMinus = itemView.findViewById(R.id.minusbtn);
}
}
来源:https://stackoverflow.com/questions/57925191/implement-view-clicks-on-multiple-viewholder-types-in-recycleview-adapter