HukeLau_DABA HukeLau_DABA - 3 months ago 16
Android Question

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

Answer

set your onclick listeners on onBindViewHolder and you can access the position from there. If you set them in your ViewHolder you wont 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 origionally doing it was correct.

when the view is clicked you can use getPosition in your view holder and it returns the position

Update

getPosition() is now deprecated and replaced with getAdapterPosition()

Comments