Perché non RecyclerView ha onItemClickListener ( ) ? e come RecyclerView è diverso da Listview ?

? Tarun Varshney @ | Original: StackOverFlow
---

Non so se io chiedo la domanda giusta . Stavo esplorando RecyclerView e sono rimasto sorpreso di vedere che RecyclerView non ha onItemClickListener() . Perché RecyclerView si estende

android.view.ViewGroup

e ListView si estende

android.widget.AbsListView

. Comunque ho risolto il mio problema scritta onClick nel mio RecyclerView.Adapter :

  public static class ViewHolder extends RecyclerView.ViewHolder implements OnClickListener {

    public TextView txtViewTitle;
    public ImageView imgViewIcon;

    public ViewHolder(View itemLayoutView) {
        super(itemLayoutView);
        txtViewTitle = (TextView) itemLayoutView.findViewById(R.id.item_title);
        imgViewIcon = (ImageView) itemLayoutView.findViewById(R.id.item_icon);
    }

    @Override
    public void onClick(View v) {
        // TODO Auto-generated method stub

    }
}

Ma ancora voglio sapere perché Google rimosso onItemClickListener() ?

C'è un problema di prestazioni o qualcos'altro ?

---

Top 5 Risposta

1MLProgrammer-CiM @

Dopo l'introduzione di ListView, onItemClickListener è stato problematico . Nel momento in cui si dispone di un ascoltatore click per alcuno degli elementi interni del callback non dovrebbe essere attivato, ma non è stato notificato o ben documentate ( se non del tutto ) e quindi c'era un sacco di confusione e SO domande su di esso .

Dato che RecyclerView prende un ulteriore passo avanti e non ha un concetto di una riga / colonna, ma piuttosto una quantità arbitrariamente disposto dei bambini, che hanno delegato l' onClick ad ognuno di loro, o al programmatore di attuazione .

Pensate a Recyclerview non come un ListView 1 : 1 sostituzione ma piuttosto come una componente più flessibile per i casi d'uso complessi . E come dici tu, la soluzione è quello che Google aspetta da voi . Ora avete un adattatore che può delegare onClick a un'interfaccia trasmesso costruttore, che è il modello corretto per entrambi ListView e 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);
}

}

e poi sulla scheda

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;
    } 

  ...

Ora guarda in quell'ultimo pezzo di codice : onCreateViewHolder(ViewGroup parent, int viewType) la firma suggerisce già diversi tipi di vista . Per ognuno di essi potrete richiedere un viewholder diverso troppo, e poi ognuno di loro può avere un diverso insieme di scatti . Oppure si può semplicemente creare un viewholder generico che prende qualsiasi vista e uno onClickListener e si applica di conseguenza . O delegare di un livello alla orchestratore così numerosi frammenti / attività hanno lo stesso elenco con un comportamento diverso click . Ancora una volta, tutto la flessibilità è dalla vostra parte .

Si tratta di un componente realmente necessario e abbastanza vicino a quello che i nostri implementazioni interne e miglioramenti ListView erano fino ad ora . E 'bene che Google finalmente riconosce esso .

2Tarun Varshney @

> Come RecyclerView è diverso da Listview ?

Una differenza è che ci sia di classe LayoutManager con RecyclerView con cui è possibile gestire il vostro RecyclerView come-

Orizzontale o verticale a scorrimento da LinearLayoutManager

GridLayout da GridLayoutManager

Staggered GridLayout da StaggeredGridLayoutManager

Come per lo scorrimento orizzontale per RecyclerView-

  LinearLayoutManager llm = new LinearLayoutManager(context);
    llm.setOrientation(LinearLayoutManager.HORIZONTAL);
    recyclerView.setLayoutManager(llm);
3Amir Fazwan @
itemLayoutView.setOnClickListener(new View.setOnClickListener() {
            @Override
            public boolean onLongClick(View v) {
                Toast.makeText(v.getContext(), "on item click", Toast.LENGTH_SHORT).show();

                return true;
            }
        });

Implementare questo costruttore ViewHolder dentro .