RecyclerView.ViewHolder是否必须是内部类?

18

我有两个使用完全相同 RecyclerView.ViewHolder 内部类的 RecyclerView.Adapter

我想消除代码重复,所以将这些 ViewHolder 作为自由的、独立的类,并使全新的类可以被任何 RecyclerView.Adapter 所使用。

然而,我遇到了许多问题,例如难以访问适配器对象。 getAdapterPosition() 总是返回 -1

所以我改变了主意,制作了一个超级的 RecyclerView.Adapter 类,这个类被那些适配器继承,并把 ViewHolder 放在超类中,这样那些适配器就可以从子类中使用它了。

但我想知道是否必须把 ViewHolder 设为内部类。这让我很烦恼。请不要建议我合并适配器类,它们完全不同,因为 ViewHolder 只是一种特殊的 viewType,可以出现在任何 RecyclerView 中。

我正在等待您更好的方法,让我感觉更好。

谢谢。


1
Java甚至没有真正的内部类,只是一些用于在同一个.java文件中编写同包类的语法糖。如果您遇到过ViewHolders作为非内部类的问题,请发布有问题的代码。 - laalto
3个回答

11

ViewHolder可以是外部类。在RecyclerView的所有教程中,内部类只是一个建议,如果您的ViewHolder需要访问所有适配器参数(即使是私有的),则这是更好的一种方式,但是通过访问适配器和ViewHolder中的访问方法可以重新创建任何访问或对象关系。

我创建了一个独立的项目,使用ViewHolder作为一个外部类,请看一下。仓库链接 - https://github.com/maciejsikora/outsideviewholder

我认为你的问题的原因也是第一个代码版本中ViewHolder是一个内部类,并且具有对属性的访问权限,将其改为外部类后,代码应该进行重构,结果应深入检查ViewHolder和Adapter之间的所有关系。

回答这个问题的答案是 - ViewHolder不必是内部类,而且您的问题是由于无效的使用ViewHolder作为外部类代码实现造成的。


我的viewHolder中有一个实现OnClickListener的按钮。当监听器被调用时,我需要知道哪个对象的按钮被点击了,因此我必须访问适配器的位置。然而,调用getAdapterPosition()会返回-1,所以我遇到了IndexOutOfBounds异常,可能你在你的项目中也会得到-1。 :) - Egemen Hamutçu
@EgemenHamutçu 我确定不是。要访问位置,请在适配器中创建getter并将适配器设置为ViewHolder。 - Maciej Sikora

7

实际上不需要

首先,您需要了解为什么需要内部类?

我们需要内部类是因为我们只希望特定的类具有此功能,例如对于许多监听器按钮 onClick 等,我们有许多内部类。

因此,我们使用内部类来使事情变得私有、简短和简单

您可以将这个东西(ViewHolder)作为一个单独的类。但这不是高效、清晰(如果您创建另一个类,它将添加一个额外的类到您的项目中)和有效的方式。


1
内部类也是“额外的类”。 - laalto
内部类实际上是非常糟糕的做法,因为它们在您的项目中是“隐藏”的。使用“每个文件一个类”的原则更加“清晰”和推荐。 - breakline
请看这个链接:https://dev59.com/QWgu5IYBdhLWcg3wU1uN - Mehraj Malik
内部类只有在您想要直接访问父对象的变量和方法时才有用。这是不良实践,因为它会紧密耦合两个类。如果您需要在两个类之间通信,则应使用接口或者更好地使用发布-订阅架构,这样您可以轻松地在测试或生产中替换类等。 - breakline
我同意,编程中有许多方法可以完成一件事。这有点类似于某些人喜欢多线程,而有些人则害怕多线程。这些因素取决于每个人。这就是为什么程序员将它们作为建议而非规则。 - Mehraj Malik
@breakline 只有在您可以在其他地方重用受影响的类时,紧密耦合才是不好的。我已经使用ReclerView很多年了,但从未感到想要在另一个适配器中重用ViewHolder的愿望。我更喜欢“以最小的努力获得预期结果”的原则。 :) 内部类尽可能干净。如果不是这样,它们就不存在了。如果我有多重继承,我就不需要它们。 - The incredible Jan

0

我一直将它用作内部。我理解你的问题,而且我也处理过一段时间,我认为这篇文章有答案。这个答案的人也遇到了适配器的问题。

在这里检查: https://dev59.com/uIjca4cB1Zd3GeqP1cSg#29719632

你的问题很有趣;)


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接