RecyclerView hat kein onItemClickListener
, denn RecyclerView ist für das Recycling von Ansichten (Überraschung!) verantwortlich, daher liegt es in der Verantwortung der Ansicht, die recycelt wird, die empfangenen Klick-Ereignisse zu behandeln.
Dies macht die Verwendung tatsächlich viel einfacher, insbesondere wenn Sie Elemente haben, die an mehreren Stellen geklickt werden können.
Wie auch immer, das Erkennen eines Klicks auf ein RecyclerView-Element ist sehr einfach. Alles, was Sie tun müssen, ist ein Interface zu definieren (wenn Sie kein Kotlin verwenden, in diesem Fall übergeben Sie einfach ein Lambda):
public class MyAdapter extends RecyclerView.Adapter {
private final Clicks clicks;
public MyAdapter(Clicks clicks) {
this.clicks = clicks;
}
private List items = Collections.emptyList();
public void updateData(List items) {
this.items = items;
notifyDataSetChanged(); // TODO: verwenden Sie bei Bedarf ListAdapter für das Differenzieren, wenn Sie Animationen benötigen
}
public interface Clicks {
void onItemSelected(MyObject myObject, int position);
}
public class MyViewHolder extends RecyclerView.ViewHolder {
private MyObject myObject;
public MyViewHolder(View view) {
super(view);
// Ansichten binden
view.setOnClickListener((v) -> {
int adapterPosition = getBindingAdapterPosition();
if(adapterPosition >= 0) {
clicks.onItemSelected(myObject, adapterPosition);
}
});
}
public void bind(MyObject myObject) {
this.myObject = myObject;
// Daten an Ansichten binden
}
}
}
Derselbe Code in Kotlin:
class MyAdapter(val itemClicks: (MyObject, Int) -> Unit): RecyclerView.Adapter() {
private var items: List = Collections.emptyList()
fun updateData(items: List) {
this.items = items
notifyDataSetChanged() // TODO: verwenden Sie bei Bedarf ListAdapter für das Differenzieren, wenn Sie Animationen benötigen
}
inner class MyViewHolder(val myView: View): RecyclerView.ViewHolder(myView) {
private lateinit var myObject: MyObject
init {
// Ansichten binden
myView.onClick {
val adapterPosition = getBindingAdapterPosition()
if(adapterPosition >= 0) {
itemClicks.invoke(myObject, adapterPosition)
}
}
}
fun bind(myObject: MyObject) {
this.myObject = myObject
// Daten an Ansichten binden
}
}
}
Die Dinge, die Sie NICHT tun müssen:
1.) Sie müssen Touch-Ereignisse nicht manuell abfangen
2.) Sie müssen nicht mit Kind-Attach-Zustandsänderungs-Listenern herumspielen
3.) Sie brauchen keine PublishSubject/PublishRelay von RxJava
Verwenden Sie einfach einen Klick-Listener.