I am using a RecyclerView with a single row layout with an ImageView and a TextView.
I want to implement a OnClickListener for the View and not for seperate ViewHolder objects. How can i get the position of the view in the Adapter?
Right now i'm deleting comments on click, but i cannot select the clicked View. I added a TODO in the appropriate line.
public class CommentAdapter extends RecyclerView.Adapter<CommentAdapter.ViewHolder> { /** List of Comment objects */ private List<Comment> mCommentList; /** Database with Comment objects */ private CommentsDataSource mDataSource; /** * Construcutor for CommentAdapter * * @param commentList List of Comment objects * @param dataSource Database with Comment objects */ public CommentAdapter(List<Comment> commentList, CommentsDataSource dataSource) { this.mCommentList = commentList; this.mDataSource = dataSource; } /** * Add Comment objects to RecyclerView * * @param position The position where the Comment object is added * @param comment Comment Object */ public void add(int position, Comment comment) { mCommentList.add(position, comment); notifyItemInserted(position); } /** * Remove Comment objects from RecyclerView * * @param comment Comment Object */ public void remove(Comment comment) { int position = mCommentList.indexOf(comment); // Avoid double tap remove if (position != -1) { mCommentList.remove(position); mDataSource.deleteComment(comment); notifyItemRemoved(position); } } @Override public ViewHolder onCreateViewHolder(final ViewGroup parent, int viewType) { final View view = LayoutInflater.from(parent.getContext()) .inflate(R.layout.single_line_row, parent, false); view.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { // TODO get position remove(mCommentList.get(getItemCount() - 1)); } }); return new ViewHolder(view); } @Override public void onBindViewHolder(ViewHolder holder, int position) { final Comment comment = mCommentList.get(position); holder.comment.setText(comment.getComment()); } @Override public int getItemCount() { return mCommentList.size(); } public static class ViewHolder extends RecyclerView.ViewHolder { /** ImageView icon */ public ImageView icon; /** TextView comment */ public TextView comment; /** * Constructor for ViewHolder * * @param itemView Layout for each row of RecyclerView */ public ViewHolder(final View itemView) { super(itemView); icon = (ImageView) itemView.findViewById(R.id.icon); comment = (TextView) itemView.findViewById(R.id.comment); } } }
It represents the ViewGroup into which the new View will be added after it is bound to an adapter position. That means the parent of the view to be added.
By default it have 5.
When used, pass the child Class Object, and in onCreateViewHolder , use Reflection to create the child ViewHolder. When you get an onBindViewHolder, just pass it to the ViewHolder.
You cannot use the position
parameter of onBindViewHolder
in a callback. If a new item is added above, RecyclerView will not rebind your item so the position is obsolete. Instead, RecyclerView provides a getAdapterPosition
method on the ViewHolder.
@Override public ViewHolder onCreateViewHolder(final ViewGroup parent, int viewType) { final View view = LayoutInflater.from(parent.getContext()) .inflate(R.layout.single_line_row, parent, false); final ViewHolder holder = new ViewHolder(view); view.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { final int position = holder.getAdapterPosition(); if (position != RecyclerView.NO_POSITION) { remove(mCommentList.get(position)); } } }); return holder; }
I've added position != RecyclerView.NO_POSITION
check because when item is removed, RecyclerView will fade out the View so it may still be clicked by the user but its adapter position will return NO_POSITION
.
you can create a method to update position in your class.
in my case I need to attach watcher
and get the position to update arraylist
. here is the example:
class DodolWatcher bla bla { private var position: Int = 0 fun updatePosition(pos:Int) { position = pos } override fun onTextChanged(charSequence: CharSequence, i: Int, i2: Int, i3: Int) { Log.d("test", position.toString()) } }
and in your onCreateViewHolder
you can attach watcher to edittext
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): RVPaymentMethodAdapter.ViewHolder { .... bla bla .... theWatcher = DodolWatcher() <-- this is the trick amount.addTextChangedListener(theWatcher) }
and you will able to update position in your bindViewHolder
like this:
override fun onBindViewHolder(viewHolder: RVPaymentMethodAdapter.ViewHolder, position: Int) { theWatcher.updatePosition(viewHolder.adapterPosition) <-- this is the trick }
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