How do I get the position selected in a RecyclerView?
To complement @tyczj answer:
Generic Adapter Pseido code:
public abstract class GenericRecycleAdapter<T, K extends RecyclerView.ViewHolder> extends RecyclerView.Adapter{
private List<T> mList;
//default implementation code
public abstract int getLayout();
@Override
public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View v = LayoutInflater.from(parent.getContext())
.inflate(getLayout(), parent, false);
return getCustomHolder(v);
}
public Holders.TextImageHolder getCustomHolder(View v) {
return new Holders.TextImageHolder(v){
@Override
public void onClick(View v) {
onItem(mList.get(this.getAdapterPosition()));
}
};
}
abstract void onItem(T t);
@Override
public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) {
onSet(mList.get(position), (K) holder);
}
public abstract void onSet(T item, K holder);
}
ViewHolder:
public class Holders {
public static class TextImageHolder extends RecyclerView.ViewHolder implements View.OnClickListener{
public TextView text;
public TextImageHolder(View itemView) {
super(itemView);
text = (TextView) itemView.findViewById(R.id.text);
text.setOnClickListener(this);
}
@Override
public void onClick(View v) {
}
}
}
Adapter usage:
public class CategoriesAdapter extends GenericRecycleAdapter<Category, Holders.TextImageHolder> {
public CategoriesAdapter(List<Category> list, Context context) {
super(list, context);
}
@Override
void onItem(Category category) {
}
@Override
public int getLayout() {
return R.layout.categories_row;
}
@Override
public void onSet(Category item, Holders.TextImageHolder holder) {
}
}
A different method - using setTag() and getTag() methods of the View class.
use setTag() in the onBindViewHolder method of your adapter
@Override public void onBindViewHolder(myViewHolder viewHolder, int position) { viewHolder.mCardView.setTag(position); }
where mCardView is defined in the myViewHolder class
private class myViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener { public View mCardView; public myViewHolder(View view) { super(view); mCardView = (CardView) view.findViewById(R.id.card_view); mCardView.setOnClickListener(this); } }
use getTag() in your OnClickListener implementation
@Override public void onClick(View view) { int position = (int) view.getTag(); //display toast with position of cardview in recyclerview list upon click Toast.makeText(view.getContext(),Integer.toString(position),Toast.LENGTH_SHORT).show(); }
see https://stackoverflow.com/a/33027953/4658957 for more details
Set your onClickListener
s on onBindViewHolder()
and you can access the position from there. If you set them in your ViewHolder
you won't know what position was clicked unless you also pass the position into the ViewHolder
EDIT
As pskink
pointed out ViewHolder
has a getPosition()
so the way you were originally doing it was correct.
When the view is clicked you can use getPosition()
in your ViewHolder
and it returns the position
Update
getPosition()
is now deprecated and replaced with getAdapterPosition()
Update 2020
getAdapterPosition()
is now deprecated and replaced with getAbsoluteAdapterPosition()
or getBindingAdapterPosition()
Kotlin code:
override fun onBindViewHolder(holder: MyHolder, position: Int) {
// - get element from your dataset at this position
val item = myDataset.get(holder.absoluteAdapterPosition)
}