简体   繁体   English

Android:将 OnClickListner 设置为 RecyclerView 中每个视图项的最佳方法

[英]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 中使用单击事件,则在onCreateViewHolderonBindViewHolder中设置单击侦听器,例如,删除项目并通知适配器或简单地显示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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM