RecyclerView.OnItemClickListener对比在ViewHolder中实现OnClickListener有何优势?
嘿,这个问题问到点子上了!作为天天和RecyclerView打交道的开发者,我可以很明确地告诉你,在ViewHolder里实现OnClickListener相比那种全局的RecyclerView.OnItemClickListener,确实有不少实打实的优势:
更贴合单一职责,内聚性更强
ViewHolder的本职工作就是管理item视图的创建、绑定和复用,把点击事件的逻辑放在这里,相当于让它全权负责自己视图的交互行为,不用把这部分逻辑甩给外部的Listener。比如你的item里有多个可点击子View(头像、操作按钮、整个item本身),直接在ViewHolder里给每个View单独设置点击监听就行,不用在外部Listener里写一堆if (view.getId() == R.id.xxx)的判断,代码清爽太多。避免冗余的视图查找,性能更优
如果用全局的OnItemClickListener,你要获取被点击item里的控件数据,得先通过recyclerView.findViewHolderForAdapterPosition(position)拿到对应的ViewHolder,再去查找具体的View。但在ViewHolder里直接处理点击的话,所有控件都是初始化好的成员变量,直接调用就行,省去了重复查找视图的开销,尤其是在列表滚动频繁的场景下,这点优化还是很实在的。逻辑更清晰,维护成本更低
当你的RecyclerView有多种item类型时,每种ViewHolder只需要关心自己类型的点击逻辑就行。以后要修改某个item的点击行为,直接找到对应的ViewHolder类改就行,不用在外部的Listener里翻找一堆混杂了不同item类型的逻辑代码,避免了把所有点击逻辑堆成“大泥球”。灵活性拉满,适配复杂场景
比如你需要给item设置状态依赖的点击行为(比如item处于禁用状态时不响应点击),直接在ViewHolder的点击回调里判断当前item的状态就行,不用在外部Listener里额外做判断。而且如果某个item类型不需要点击功能,直接不用实现OnClickListener,完全按需定制,非常灵活。减少回调层级,代码更简洁
用全局Listener的话,通常要在Adapter里定义一个回调接口,然后让Activity/Fragment实现这个接口,再把实例传递给Adapter,链路绕了好几层。而ViewHolder里处理点击的话,简单逻辑可以直接在内部处理,需要通知外部的话,直接调用Adapter里的方法就行,回调链路更短,代码结构更清晰。
当然啦,也不是说全局的OnItemClickListener完全没用——比如你需要统一统计所有item的点击事件,这种全局监听的方式会更方便。但在日常开发的大多数场景下,在ViewHolder里实现点击监听确实是更主流、更推荐的方案。
内容的提问来源于stack exchange,提问作者EdgeDev

