[英]Android: Best way to set OnClickListner to each view item in RecyclerView
I am currently trying to set an onClickListner to each item of the list in my RecyclerView.我目前正在尝试为我的 RecyclerView 中列表的每个项目设置一个 onClickListner。 I was wondering which method is the best to this and the pros and cons of each.我想知道哪种方法最适合这个以及每种方法的优缺点。
I found two ways.我找到了两种方法。 This one seems more simpler:这个看起来更简单:
RecyclerView onClick 回收查看 onClick
They just add it to each item in the onCreateViewHolder()
method他们只是将它添加到onCreateViewHolder()
方法中的每个项目
private final OnClickListener mOnClickListener = new MyOnClickListener();
@Override
public MyViewHolder onCreateViewHolder(final ViewGroup parent, final int viewType) {
View view = LayoutInflater.from(mContext).inflate(R.layout.myview, parent, false);
view.setOnClickListener(mOnClickListener);
return new MyViewHolder(view);
}
The method in this article seems more confusing to me which is creating an interface in the adapter class and implementing it in the Activity file:本文中的方法对我来说似乎更令人困惑,它是在适配器 class 中创建一个接口并在 Activity 文件中实现它:
https://medium.com/androiddevelopers/android-data-binding-recyclerview-db7c40d9f0e4 https://medium.com/androiddevelopers/android-data-binding-recyclerview-db7c40d9f0e4
What would be the benefit of doing it this way?这样做有什么好处?
I am answering based on what I understood.我根据我的理解来回答。
There are two places you can attach the listener.有两个地方可以附加监听器。
OnCreateViewHolder
This function is called whenever recyclerview
can't reuse any existing views and needs to inflate a new view.每当recyclerview
无法重用任何现有视图并需要扩充新视图时,都会调用此 function。 Remember recyclerview
reuses the views which are out of focus.请记住, recyclerview
会重用失焦的视图。
onBindViewHolder
This function is called whenever any view is coming on the screen and recyclerview
wants you to add the proper content to that view.每当屏幕上出现任何视图时都会调用此 function 并且recyclerview
希望您向该视图添加适当的内容。
So at both these functions, you have access to your view and you can set click listeners, the only difference is that in onCreateViewHolder
you don't have access to position of the item (remember it doesn't create view for each position it might reuse out of focus views) and in onBindViewHolder
you have access to position of the item.因此,在这两个函数中,您都可以访问视图并且可以设置点击侦听器,唯一的区别是在onCreateViewHolder
中您无法访问项目的 position(请记住,它不会为每个 position 创建视图,它可能重用焦点视图)并且在onBindViewHolder
中,您可以访问项目的 position。
So basically if you need the position of the item for which the view is clicked then you should set it in onBindViewHolder
otherwise you can set it in onCreateViewHolder
.因此,基本上,如果您需要单击视图的项目的 position ,则应将其设置在onBindViewHolder
中,否则您可以将其设置在onCreateViewHolder
中。
I hope this helps.我希望这有帮助。 If not please add a comment.如果没有,请添加评论。
Set click listener in onCreateViewHolder
or onBindViewHolder
if you need to consume the click event in Adapter
class only eg, removing an item and notifying the adapter or simply show Toast
.如果您只需要在Adapter
class 中使用单击事件,则在onCreateViewHolder
或onBindViewHolder
中设置单击侦听器,例如,删除项目并通知适配器或简单地显示Toast
。 Only difference is that you get position
inside onBindViewHolder
.唯一的区别是您在onBindViewHolder
position
Second approach of using interface and implementing it in Activity/Fragment
is for cases where you need to receive the click event in these parent classes.第二种使用接口并在Activity/Fragment
中实现它的方法是针对需要在这些父类中接收点击事件的情况。 You pass the interface instance from Activity/Fragment
to adapter class and interface method is invoked on click.您将接口实例从Activity/Fragment
传递给适配器 class 并在单击时调用接口方法。 For better understanding, you can consider the case where you need to make an API call or invoke a ViewModel/Controller
function on click of adapter item.为了更好地理解,您可以考虑在单击适配器项时需要进行 API 调用或调用ViewModel/Controller
function 的情况。
So, both the cases are valid based on your use case.因此,根据您的用例,这两种情况都是有效的。 Hope it helps:)希望能帮助到你:)
Indeed the best approach would be to attach ClickListner
to the onBindViewHolder
, as the method called once for each child of the recyclerview
.实际上,最好的方法是将ClickListner
附加到onBindViewHolder
,因为该方法为recyclerview
的每个子项调用一次。 Check out this snippet:看看这个片段:
@Override
public void onBindViewHolder(@NonNull ViewHolder holder, final int position) {
final Contact contact = contactListFiltered.get(position);
holder.tvContactName.setText(contact.personUri.toString());
holder.tvContactNo.setText(contact.number);
holder.civContactPic.setImageBitmap(contact.photo);
holder.cvContactItem.setOnClickListener(v -> Utils.shortToast("" + contact.id, context));
}
On click, it will show contact-id of each child of recyclerview
in a toast.单击时,它将在 toast 中显示recyclerview
的每个孩子的联系人 ID。 On the other hand, if you add ClickListner
to onCreateViewHolder
, you cant detect which item get clicked and it acts similar to each child of recyclerview
, which I don't think you want.另一方面,如果将ClickListner
添加到onCreateViewHolder
,则无法检测到单击了哪个项目,并且它的行为类似于recyclerview
的每个子项,我认为您不希望这样做。 So I suggest you to add your ClickListner
to onCreateViewHolder
.因此,我建议您将ClickListner
添加到onCreateViewHolder
。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.