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.
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.
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) }
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
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With