1048 Stimmen

Warum hat RecyclerView keine onItemClickListener()?

Ich habe RecyclerView erkundet und war überrascht zu sehen, dass RecyclerView keine onItemClickListener() hat.

Ich habe zwei Fragen.

Hauptfrage

Ich möchte wissen, warum Google onItemClickListener() entfernt hat?

Gibt es ein Leistungsproblem oder etwas anderes?

Nebenfrage

Ich habe mein Problem gelöst, indem ich onClick in meinem RecyclerView.Adapter geschrieben habe:

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) {

    }
}

Ist das okay / gibt es einen besseren Weg?

10voto

chad Punkte 141

Nachdem ich die Antwort von @MLProgrammer-CiM gelesen habe, hier ist mein Code:

class NormalViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener{

    @Bind(R.id.card_item_normal)
    CardView cardView;

    public NormalViewHolder(View itemView) {
        super(itemView);
        ButterKnife.bind(this, itemView);
        cardView.setOnClickListener(this);
    }

    @Override
    public void onClick(View v) {
        if(v instanceof CardView) {
            // Verwenden Sie getAdapterPosition() anstelle von getLayoutPosition()
            int itemPosition = getAdapterPosition();
            removeItem(itemPosition);
        }
    }
}

10voto

Hiren Patel Punkte 50526

Ich habe es auf diese Weise gemacht, es ist sehr einfach:

Fügen Sie einfach 1 Zeile für die angeklickte RecyclerView-Position hinzu:

int position = getLayoutPosition()

Vollständiger Code für die ViewHolder-Klasse:

private class ChildViewHolder extends RecyclerView.ViewHolder {
        public ImageView imageView;
        public TextView txtView;

        public ChildViewHolder(View itemView) {
            super(itemView);
            imageView= (ImageView)itemView.findViewById(R.id.imageView);
            txtView= (TextView) itemView.findViewById(R.id.txtView);
            itemView.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View view) {
                    Log.i("Klick-Position des RecyclerView-Elements", String.valueOf(getLayoutPosition()));
                }
            });
        }
    }

Hoffentlich wird Ihnen das helfen.

8voto

tmac12 Punkte 233

Ich verwende diese Methode, um ein Intent von RecyclerView aus zu starten:

@Override
 public void onBindViewHolder(ViewHolder viewHolder, int i) {

    final MyClass myClass = mList.get(i);
    viewHolder.txtViewTitle.setText(myclass.name);
   ...
    viewHolder.itemView.setOnClickListener(new View.OnClickListener() {
      @Override
       public void onClick(View v){
             Intent detailIntent = new Intent(mContext, type.class);                                                            
             detailIntent.putExtra("MyClass", myclass);
             mContext.startActivity(detailIntent);
       }
}
);

5voto

Simon Punkte 3150

Hier ist eine Möglichkeit, es recht einfach zu implementieren, wenn Sie eine Liste von POJOs haben und einen davon von außerhalb des Adapters abrufen möchten.

In Ihrem Adapter erstellen Sie einen Listener für die Klick-Ereignisse und eine Methode, um ihn festzulegen:

public class MyAdapter extends RecyclerView.Adapter {
...
private List mMyPojos;
private static OnItemClickListener mOnItemClickListener;
...
public interface OnItemClickListener {
    public void onItemClick(MyPojo pojo);
}
...
public void setOnItemClickListener(OnItemClickListener onItemClickListener){
    mOnItemClickListener = onItemClickListener;
}
...

}

In Ihrem ViewHolder setzen Sie onClickListener um und erstellen ein Klassenmember, um vorübergehend das POJO zu speichern, das die Ansicht darstellt:

public static class ViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener {
    public MyPojo mCurrentPojo;
    ...
    public ViewHolder(View view) {
        super(v);
        ...
        view.setOnClickListener(this); //Sie könnten dies auch auf einem Teil des Layouts setzen
    }
    ...
    @Override
    public void onClick(View view) {
        if(mOnItemClickListener != null && mCurrentPojo != null){
            mOnItemClickListener.onItemClick(mCurrentPojo);
        }
    }

Zurück in Ihrem Adapter, setzen Sie das aktuelle POJO, wenn der ViewHolder gebunden ist (oder auf null, wenn die aktuelle Ansicht keins hat):

@Override
public void onBindViewHolder(final ViewHolder holder, final int position) {
    final MyPojo currentPojo = mMyPojos.get(position); 
    holder.mCurrentPojo = currentPojo;
    ...

Das war es, jetzt können Sie es von Ihrem Fragment/Ihrer Aktivität aus wie folgt verwenden:

    mMyAdapter.setOnItemClickListener(new mMyAdapter.OnItemClickListener() {
        @Override
        public void onItemClick(MyPojo pojo) {
            //Hier können Sie tun, was Sie wollen mit Ihrem Pojo
        }
    });

5voto

cryyyyy Punkte 619

Wenn Sie onClick() zum Child-View der Elemente hinzufügen möchten, zum Beispiel einem Button im Element, habe ich festgestellt, dass Sie dies ganz einfach in onCreateViewHolder() Ihres eigenen RecyclerView.Adapter tun können, genau wie folgt:

        @Override
        public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
            View v = LayoutInflater
                    .from(parent.getContext())
                    .inflate(R.layout.cell, null);

            Button btn = (Button) v.findViewById(R.id.btn);
            btn.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    //machen
                }
            });

            return new MyViewHolder(v);
        }

Ich weiß nicht, ob es ein guter Weg ist, aber es funktioniert gut. Wenn jemand eine bessere Idee hat, bin ich sehr froh, wenn er mir Bescheid sagt und meine Antwort korrigiert! :)

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X