Warum nicht RecyclerView onItemClickListener haben () ? und Wie RecyclerView ist anders als Listview ?

? Tarun Varshney @ | Original: StackOverFlow
---

Ich weiß nicht, ob ich die richtige Frage . Ich war zu erkunden RecyclerView und ich war überrascht zu sehen, dass RecyclerView muss nicht onItemClickListener() . Denn RecyclerView erweitert

android.view.ViewGroup

und ListView erweitert

android.widget.AbsListView

. Allerdings habe ich mein Problem gelöst durch Schreiben onClick in meinem 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

    }
}

Aber ich will wissen, warum Google entfernt onItemClickListener() ?

Gibt es ein Performance-Problem oder etwas anderes?

---

Top 5 Antwort

1MLProgrammer-CiM @

Seit der Einführung der ListView, onItemClickListener problematisch gewesen . Sobald Sie haben eine Klick -Listener für einen der inneren Elemente der Rückruf nicht ausgelöst werden, aber es wurde nicht mitgeteilt oder gut dokumentiert ( wenn überhaupt), so gab es eine Menge Verwirrung und SO Fragen zu diesem Thema .

Da die RecyclerView geht noch einen Schritt weiter und hat kein Konzept einer Zeile / Spalte, sondern eine willkürlich angelegten Betrag der Kinder, sie die onClick auf jeden von ihnen zugewiesen worden sein, oder die Umsetzung Programmierer .

Denken Sie an Recyclerview nicht als ListView 1: 1- Ersatz, sondern als flexibler Baustein für komplexe Anwendungsfälle . Und wie Sie sagen, ist Ihre Lösung, was Google von Ihnen erwartet wird . Jetzt haben Sie einen Adapter, der onClick auf einer Schnittstelle an den Konstruktor übergeben, die das richtige Muster für beide ListView und Recyclerview ist delegieren kann .

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

}

und dann auf Ihrem Adapter

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

  ...

Nun ein Blick in dieses letzte Stück Code : onCreateViewHolder(ViewGroup parent, int viewType) die Signatur verschiedenen Ansichtstypen vorschlagen bereits . Für jeden von ihnen Sie einen anderen viewholder zu erfordern, und anschließend jeder von ihnen eine andere Gruppe von Klicks haben kann . Oder Sie können einfach erstellen eine generische viewholder, die jeden Blick und ein OnClickListener nimmt und gilt entsprechend. Oder delegieren eine Ebene nach oben zu der Orchestrierung so mehrere Fragmente / Tätigkeiten haben die gleiche Liste mit unterschiedlichen Klickverhalten . Wieder ist alles, Flexibilität auf Ihrer Seite.

Es ist ein wirklich gebraucht Komponente und ziemlich nah an, was unsere internen Implementierungen und Verbesserungen Listview waren bis jetzt. Es ist gut, dass Google endlich eingesteht .

2Tarun Varshney @

> Wie RecyclerView aus Listview anders?

Ein Unterschied besteht darin, dass es LayoutManager Klasse mit RecyclerView mit dem Sie verwalten RecyclerView wie- kann

Horizontale oder vertikale Scrollen durch LinearLayoutManager

Gridlayout durch GridLayoutManager

Gestaffelte Gridlayout durch StaggeredGridLayoutManager

Wie für den horizontalen Bildlauf für 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;
            }
        });

Implementieren Sie diese innerhalb ViewHolder Konstruktor .