677 Stimmen

RecyclerView onClick

Hat jemand, der RecyclerView verwendet, einen Weg gefunden, um einen onClickListener für Elemente im RecyclerView festzulegen? Ich dachte daran, für jedes Element einen Listener für jedes Layout festzulegen, aber das scheint etwas zu umständlich zu sein. Ich bin sicher, dass es eine Möglichkeit gibt, dass der RecyclerView auf das onClick-Ereignis hört, aber ich kann es nicht ganz herausfinden.

5voto

4gus71n Punkte 4041

Für mich ist das der beste Weg:

class YourRecyclerAdapter extends RecyclerView.Adapter implements View.OnClickListener { 
  ...
  @Override
  public void onClick(View view) {
        int itemPosition = vRecycle.getChildPosition(view);
        //Und verwenden itemPosition, um den Artikel aus Ihrer Sammlung zu erhalten. Auf diese Weise beschränken Sie den ViewHolder nicht mit einem OnClick-Callback
    }
  ...
}

5voto

Muhammad Riyaz Punkte 2572

Hier ist, was ich gemacht habe Hier weiterlesen und den Gist herunterladen

Hier dasselbe hinzufügen

CustomItemClickListener.java

public interface CustomItemClickListener {
 public void onItemClick(View v, int position);
}

ItemsListAdapter.java

public class ItemsListAdapter extends RecyclerView.Adapter {
ArrayList data;

Context mContext;
CustomItemClickListener listener;

@Override
public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
    View mView = LayoutInflater.from(parent.getContext()).inflate(R.layout.items_list_single_item, parent, false);
    final ViewHolder mViewHolder = new ViewHolder(mView);
    mView.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            listener.onItemClick(v, mViewHolder.getAdapterPosition());
        }
    });
    return mViewHolder;
}

@Override
public void onBindViewHolder(ViewHolder holder, int position) {
    holder.itemTitle.setText(Html.fromHtml(data.get(position).getTitle()));
    if (!TextUtils.isEmpty(data.get(position).getThumbnailURL())) {
      // Ich liebe die Picasso-Bibliothek :) http://square.github.io/picasso/
        Picasso.with(mContext).load(data.get(position).getThumbnailURL()).error(R.drawable.ic_no_image).
                placeholder(R.drawable.ic_no_image).
                transform(new RoundedCornersTransformation(5, 0)).
                into(holder.thumbnailImage);
    } else {
        holder.thumbnailImage.setImageResource(R.drawable.ic_no_image);
    }
}

@Override
public int getItemCount() {
    return data.size();
}

public ItemsListAdapter(Context mContext, ArrayList data, CustomItemClickListener listener) {
    this.data = data;
    this.mContext = mContext;
    this.listener = listener;
}

public static class ViewHolder extends RecyclerView.ViewHolder {
    public TextView itemTitle;
    public ImageView thumbnailImage;

    ViewHolder(View v) {
        super(v);
        itemTitle = (TextView) v
                .findViewById(R.id.post_title);
        thumbnailImage = (ImageView) v.findViewById(R.id.post_thumb_image);
    }
 }
}

4voto

Ein Klick-Listener wird innerhalb Ihres ViewHolder auf folgende Weise eingerichtet:

public class MyViewHolder extends RecyclerView.ViewHolder {
    public TextView title, year, genre;

    public MyViewHolder(View view) {
        super(view);

        title = (TextView) view.findViewById(R.id.title);
        genre = (TextView) view.findViewById(R.id.genre);
        year = (TextView) view.findViewById(R.id.year);

        view.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                Toast.makeText(context, ""+getAdapterPosition(), Toast.LENGTH_SHORT).show();
            }
        });
    }
}

4voto

Akah Punkte 1229

Aus den meisten der obigen Antworten scheinen sie ihre onclicklistener auf einzelne Elemente zu setzen. Die Lösung, die ich gleich anbieten werde, ist jedoch sehr einfach, aber für viele nicht intuitiv. Viele vergessen, dass die anderen Komponenten immer in einer übergeordneten Komponente sind, die verwendet wird, um Elemente in den Listen- oder Recycler-Ansichten anzuzeigen. Diese Lösung besteht darin, einen einzigen onclick-Listener auf diese übergeordnete Ansicht zu setzen und dann wird die Aktion ausgeführt. Die Lösung beinhaltet auch eine Möglichkeit, die Position des angeklickten Elements aus der Liste oder RecyclerView zu übergeben. Hier ist unser Haupt-Rootview eine CardView aus der Android-Support-Bibliothek. Hier ist ein Beispielcode

public class ListAdapter extends RecyclerView.Adapter {

public static final String LOG_TAG = ListAdapter.class.getSimpleName();
private Cursor mDataset;
private Context mContext;
private ViewHolder mViewHolder;

// Bieten Sie einen geeigneten Konstruktor an (abhängig von der Art des Datensatzes)
public ListAdapter(Context context, Cursor Dataset) {
    mDataset = Dataset;
    mContext = context;
}

// Erstellen neuer Ansichten (aufgerufen vom Layout-Manager)
@Override
public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {

    // neue Ansicht erstellen
    View v = LayoutInflater.from(parent.getContext())
            .inflate(R.layout.list_business_view, parent, false);

    mViewHolder = new ViewHolder(v);
    return mViewHolder;
}

public void setData(Cursor newdata) {
    this.mDataset = newdata;
}

// Ersetzen Sie den Inhalt einer Ansicht (aufgerufen vom Layout-Manager)
@Override
public void onBindViewHolder(ViewHolder holder, int position) {
// Daten an andere Elemente binden. Um Zeit zu sparen, habe ich das hier ausgelassen.
           //Hier setzen wir einen Klicklistener für ein Element in der Recycler-Liste anstelle jedes Elements eines bestimmten Elements.
            holder.card.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    Toast.makeText(mContext, " Nur auf Element an Position geklickt " + itemPosition, Toast.LENGTH_LONG).show();

            }
        });

    }
}

// Gib die Größe deines Datensatzes zurück (aufgerufen vom Layout-Manager)
@Override
public int getItemCount() {
    if (null != mDataset) {
        return mDataset.getCount();
    }
    return 0;

}

// Bieten Sie einen Verweis auf die Ansichten für jedes Datenelement an
// Komplexe Datenelemente benötigen möglicherweise mehr als eine Ansicht pro Element, und
// Sie haben Zugriff auf alle Ansichten für ein Datenelement in einem Ansichtshalter
public static class ViewHolder extends RecyclerView.ViewHolder{
    // jedes Datenelement ist in diesem Fall nur ein String
    public final TextView mBusinesssName; // Ansicht für den Firmennamen
    public final TextView mBusinessCategory; // Ansicht für den Kategorienamen
    public final ImageView businessImage; // Ansicht für das Bild der Firmenkategorie
    public final TextView mBusinessDistance; // Ansicht für die Entfernung
    public final CardView card;

    public ViewHolder(View view) {
        super(view);
        mBusinesssName = (TextView) view.findViewById(R.id.list_item_name_textview);
        mBusinessCategory = (TextView) view.findViewById(R.id.list_item_category_textview);
        mBusinessDistance = (TextView) view.findViewById(R.id.list_item_dist_textview);
        businessImage = (ImageView) view.findViewById(R.id.list_item_icon);
        card = (CardView) view.findViewById(R.id.card_view);

    }
}
}

4voto

Nilesh Deokar Punkte 2907

Kotlin-Implementierung von nhaarman's Antwort:

mRecyclerView.addOnItemTouchListener(object  : RecyclerItemClickListener(this, mRecyclerView,object :RecyclerItemClickListener.OnItemClickListener{
            override fun onItemClick(view: View, position: Int) {

            }

            override fun onLongItemClick(view: View?, position: Int) {

            }
}){})

RecyclerItemClickListener.java :

import android.content.Context
import android.support.v7.widget.RecyclerView
import android.view.GestureDetector
import android.view.MotionEvent
import android.view.View

open class RecyclerItemClickListener(context: Context, recyclerView: RecyclerView, private val mListener: OnItemClickListener?) : RecyclerView.OnItemTouchListener {

    private var mGestureDetector: GestureDetector

    interface OnItemClickListener {
        fun onItemClick(view: View, position: Int)

        fun onLongItemClick(view: View?, position: Int)
    }

    init {
        mGestureDetector = GestureDetector(context, object : GestureDetector.SimpleOnGestureListener() {
            override fun onSingleTapUp(e: MotionEvent): Boolean {
                return true
            }

            override fun onLongPress(e: MotionEvent) {
                val child = recyclerView.findChildViewUnder(e.x, e.y)
                if (child != null && mListener != null) {
                    mListener.onLongItemClick(child, recyclerView.getChildAdapterPosition(child))
                }
            }
        })
    }

    override fun onInterceptTouchEvent(view: RecyclerView, e: MotionEvent): Boolean {
        val childView = view.findChildViewUnder(e.x, e.y)
        if (childView != null && mListener != null && mGestureDetector.onTouchEvent(e)) {
            mListener.onItemClick(childView, view.getChildAdapterPosition(childView))
            return true
        }
        return false
    }

    override fun onTouchEvent(view: RecyclerView, motionEvent: MotionEvent) {}

    override fun onRequestDisallowInterceptTouchEvent(disallowIntercept: Boolean) {}
}

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