Depuis l'introduction de la ListView, onItemClickListener a été problématique. Le moment où vous avez un écouteur de clics pour l'un quelconque des éléments internes de la fonction de rappel ne serait pas déclenché, mais il n'était pas informé ou bien documenté (si) donc il y avait beaucoup de confusion et DONC des questions à ce sujet.
Étant donné que RecyclerView prend un peu plus loin et ne pas avoir un concept d'une ligne/colonne, mais plutôt arbitrairement fixés montant de leurs enfants, ils ont délégué la onClick pour chacun d'eux, ou de programmeur de mise en œuvre.
Pensez à Recyclerview pas comme une ListView remplacement 1:1, mais plutôt comme un composant plus flexible pour des complexes de cas d'utilisation. Et comme vous le dites, votre solution est-ce que google attend de vous. Maintenant vous avez une carte qui peut déléguer onClick à une interface passé sur le constructeur, qui est le bon modèle pour les deux ListView et Recyclerview.
public static class ViewHolder extends RecyclerView.ViewHolder implements OnClickListener {
public TextView txtViewTitle;
public ImageView imgViewIcon;
public IMyViewHolderClicks mListener;
public ViewHolder(View itemLayoutView, IMyViewHolderClicks listener) {
super(itemLayoutView);
mListener = listener;
txtViewTitle = (TextView) itemLayoutView.findViewById(R.id.item_title);
imgViewIcon = (ImageView) itemLayoutView.findViewById(R.id.item_icon);
imgViewIcon.setOnClickListener(this);
// Is this needed or handled automatically by RecyclerView.ViewHolder?
itemLayoutView.setOnClickListener(this);
}
@Override
public void onClick(View v) {
if (v instanceof Imageview){
mListener.onTomato((ImageView)v)
} else {
mListener.onPotato(v);
}
}
public static interface IMyViewHolderClicks {
public void onPotato(View caller);
public void onTomato(ImageView callerImage);
}
}
et puis sur votre carte
public class MyAdapter extends RecyclerView.Adapter<MyAdapter.ViewHolder> {
String[] mDataset = { "Data" };
@Override
public MyAdapter.ViewHolder onCreateViewHolder(ViewGroup parent,
int viewType) {
View v = LayoutInflater.from(parent.getContext())
.inflate(R.layout.my_layout, parent, false);
MyAdapter.ViewHolder vh = new ViewHolder(v, new MyAdapter.ViewHolder.IMyViewHolderClicks() {
public void onPotato(View caller) { Log.d("Poh-tah-tos"); };
public void onTomato(ImageView callerImage) { Log.d("To-m8-tohs"); }
});
return vh;
}
// Replace the contents of a view (invoked by the layout manager)
@Override
public void onBindViewHolder(ViewHolder holder, int position) {
// Get element from your dataset at this position
// Replace the contents of the view with that element
// Clear the ones that won't be used
holder.txtViewTitle.setText(mDataset[position]);
}
// Return the size of your dataset (invoked by the layout manager)
@Override
public int getItemCount() {
return mDataset.length;
}
...
Maintenant, regardez dans ce dernier morceau de code: onCreateViewHolder(ViewGroup parent, int viewType)
à la signature d'ores et déjà proposer différents types de vues. Pour chacun d'eux, vous aurez besoin d'un autre viewholder trop, et par la suite, chaque un seul d'entre eux peut avoir un ensemble différent de clics. Ou vous pouvez simplement créer un générique viewholder qui prend n'importe quelle vue et un onClickListener et s'applique en conséquence. Ou délégué d'un niveau à l'orchestrator plusieurs fragments/activités qui ont la même liste avec différents sur le comportement. Encore une fois, toute la souplesse est de votre côté.
C'est vraiment une composante nécessaire et assez proche de ce que nos implémentations internes et des améliorations à la liste ont été jusqu'à maintenant. Il est bon que Google reconnaît.