Получение ссылки на ViewHolder на RecyclerView Click
Это моя первая попытка реализовать RecyclerView
. Я реализовал интерфейс Callback
между классами Adapter
и ViewHolder
для обработки щелчков событий на элементах пользовательского интерфейса (кнопки). У меня возникают проблемы с получением ссылки на ViewHolder
, в которой произошел щелчок. Я могу щелкнуть по Button
для первого элемента в списке, однако действие, которое я определил, выполняется в последнем ViewHolder
в мой просмотр recycler. Я, наконец, решил передать позицию через мой интерфейс, но я изо всех сил пытаюсь понять, как получить от него ссылку на этого зрителя.
public class RoomAdapter extends RecyclerView.Adapter<RoomAdapter.RoomViewHolder>
{
List<Room> mRooms;
public RoomAdapter(List<Room> rooms) {
mRooms = rooms;
}
@Override
public RoomViewHolder onCreateViewHolder(ViewGroup viewGroup, int i) {
final View viewItem = LayoutInflater
.from(viewGroup.getContext())
.inflate(R.layout.room_rv_item,viewGroup,false);
return vh = new RoomViewHolder(viewItem,new IRoomViewClick() {
@Override
public void editname(int pos) {
}
});
}
@Override
public void onBindViewHolder(RoomViewHolder roomViewHolder, int i) {
Room r = getItem(i);
roomViewHolder.label.setText(r.name);
}
public Room getItem(int position)
{
return mRooms.get(position);
}
@Override
public long getItemId(int position) {
return mRooms.get(position).getId();
}
@Override
public int getItemCount() {
return mRooms.size();
}
public static class RoomViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener
{
TextView label;
Button editBtn;
LinearLayout labelView;
Button saveBtn;
Button deleteBtn;
EditText editNameET;
IRoomViewClick mListener;
public RoomViewHolder(View itemView, IRoomViewClick listener) {
super(itemView);
labelView = (LinearLayout) itemView.findViewById(R.id.labelview);
mListener = listener;
editBtn =(Button) itemView.findViewById(R.id.editbtn);
editBtn.setOnClickListener(this);
label = (TextView) itemView.findViewById(R.id.room_listitem_label);
}
@Override
public void onClick(View view) {
int pos = getPosition();
mListener.editname(pos);
}
}
public static interface IRoomViewClick
{
public void editname(int pos);
}
}
![enter image description here]()
Ответы
Ответ 1
вы можете установить тег для editBtn
в onBindViewHolder
:
public RoomViewHolder(View itemView, IRoomViewClick listener) {
....
editBtn =(Button) itemView.findViewById(R.id.editbtn);
//add tag for this view
editBtn.setTag(this);
....
}
и получить его в onClick
@Override
public void onClick(View view) {
//getTag
RoomViewHolder holder = (RoomViewHolder )(view.getTag());
int pos = getPosition();
mListener.editname(pos);
...
}
Ответ 2
На самом деле вы можете сделать лучше, чем getTag
, вызывая getChildViewHolder(View child)
в RecyclerView:
@Override
public void onClick(View v) {
MyHolder holder = (MyHolder) mRecyclerView.getChildViewHolder(v);
holder.textView.setText("Clicked!");
}
Ответ 3
@Override
public void onClick(View v) {
int pos = getAdapterPosition(); //getPosition() is deprecated
notifyItemChanged(pos);
}
notifyItemChanged уведомит ваш onBindViewHolder, тогда вы можете сделать что-то вроде этого
public void onBindViewHolder(RoomViewHolder roomViewHolder, int i) {
Room r = getItem(i);
roomViewHolder.label.setText(r.name);
if(i == pos){ // Do Something }
}
Всякий раз, когда вы нажимаете на элемент, он изменит значение pos и вызовет //Do Something
Ответ 4
Выясните, что RecycleView
сохраняет позицию вида в параметрах макета представления, поэтому, если вы хотите, чтобы позиция представления была в нужном элементе из списка, вы можете использовать это:
RecyclerView.LayoutParams lp = (RecyclerView.LayoutParams) v.getLayoutParams();
lp.getViewPosition();
Ответ 5
Ни один из решений не работал для меня, поэтому мне пришлось иметь дело с наихудшим сценарием. Я должен обновлять ссылку на держатель при каждом прокрутке пользователя.
listAudio.addOnScrollListener(new RecyclerView.OnScrollListener() {
@Override
public void onScrolled(RecyclerView recyclerView, int dx, int dy) {
super.onScrolled(recyclerView, dx, dy);
if (audioOptionAdapter != null) {
audioOptionAdapter.notifyDataSetChanged();
}
}
});