Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do I get the position selected in a RecyclerView?

I am experimenting with the support library's recyclerview and cards. I have a recyclerview of cards. Each card has an 'x' icon at the top right corner to remove it:

The card xml, list_item.xml:

<?xml version="1.0" encoding="utf-8"?> <android.support.v7.widget.CardView xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" android:layout_margin="5dp"> <RelativeLayout     android:layout_width="match_parent"     android:layout_height="match_parent">     <TextView         android:id="@+id/taskDesc"         android:layout_width="wrap_content"         android:layout_height="wrap_content"         android:layout_alignParentBottom="true"         android:textSize="40sp"         android:text="hi"/>     <ImageView         android:id="@+id/xImg"         android:layout_width="wrap_content"         android:layout_height="wrap_content"         android:layout_alignParentTop="true"         android:layout_alignParentRight="true"         android:src="@drawable/ic_remove"/> </RelativeLayout> </android.support.v7.widget.CardView> 

I attempted to tag the row with the position I would use in notifyItemRemoved(position) in TaskAdapter.java:

public class TaskAdapter extends RecyclerView.Adapter<TaskAdapter.TaskViewHolder>  {  private List<Task> taskList; private TaskAdapter thisAdapter = this;   // cache of views to reduce number of findViewById calls public static class TaskViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener {     protected TextView taskTV;     protected ImageView closeBtn;     public TaskViewHolder(View v) {         super(v);         taskTV = (TextView)v.findViewById(R.id.taskDesc);     }      @Override     public void onClick(View v) {         int position = v.getTag();         adapter.notifyItemRemoved(position);     } }   public TaskAdapter(List<Task> tasks) {     if(tasks == null)         throw new IllegalArgumentException("tasks cannot be null");     taskList = tasks; }   // onBindViewHolder binds a model to a viewholder @Override public void onBindViewHolder(TaskViewHolder taskViewHolder, int pos) {     final int position = pos;     Task currTask = taskList.get(pos);     taskViewHolder.taskTV.setText(currTask.getDescription());      taskViewHolder.closeBtn.setOnClickListener(new View.OnClickListener() {         @Override         public void onClick(View v) {             thisAdapter.notifyItemRemoved(position);         }     }); }  @Override public int getItemCount() {     return taskList.size(); }   // inflates row to create a viewHolder @Override public TaskViewHolder onCreateViewHolder(ViewGroup parent, int pos) {     View itemView = LayoutInflater.from(parent.getContext()).                                    inflate(R.layout.list_item, parent, false);      return new TaskViewHolder(itemView); } } 

This won't work because you can't set a tag nor can I access the adapter from onClick.

like image 303
HukeLau_DABA Avatar asked Oct 31 '14 19:10

HukeLau_DABA


People also ask

What is RecyclerView selection?

List UI is a very common thing in Android Applications. Pretty much every single app has a list of something they want to display. RecyclerView Selection is a library that will allow you to handle item selection a lot easier.


2 Answers

Set your onClickListeners 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)     } 
like image 132
tyczj Avatar answered Sep 18 '22 20:09

tyczj


A different method - using setTag() and getTag() methods of the View class.

  1. 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);            }        } 
  2. 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

like image 22
bastien Avatar answered Sep 22 '22 20:09

bastien