RecyclerView.ViewHolder 是不是总是必须是内部类?

Posted

技术标签:

【中文标题】RecyclerView.ViewHolder 是不是总是必须是内部类?【英文标题】:Does RecyclerView.ViewHolder always have to be an inner class?RecyclerView.ViewHolder 是否总是必须是内部类? 【发布时间】:2016-09-06 10:37:41 【问题描述】:

我有两个RecyclerView.Adapters 使用完全相同的RecyclerView.ViewHolders 作为内部类。

我想摆脱代码重复并让这些ViewHolders 免费、独立的类,所以现在任何RecyclerView.Adapters 都可以使用全新的类。

但是我遇到了很多麻烦,例如难以访问适配器对象。 getAdapterPosition() 总是返回 -1

所以我改变了主意,创建了一个由这些适配器扩展的超级 RecyclerView.Adapter 类,并将 ViewHolder 放在超类中,以便这些适配器可以从子类中使用它。

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

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

问候。

【问题讨论】:

Java 甚至没有真正的内部类,只是在同一个 .java 文件中编写相同包类的一些语法糖。如果您在将 ViewHolders 作为非内部类时遇到问题,请发布有问题的代码。 【参考方案1】:

ViewHolder 可以在类之外。内部类只是 RecyclerView 的所有教程中的一个命题,如果您的 ViewHolder 应该可以访问所有 Adapter 参数,即使是那些私有的,这是一个更好的方法,但是任何访问或对象关系都可以通过 Adapter 和 ViewHolder 中的访问方法重新创建。

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

我认为您的问题的原因还在于,在第一个代码版本中 ViewHolder 是一个内部类并且可以访问属性,在更改为外部类之后,代码应该已经被重构,并且结果ViewHolder 和 Adapter 之间的所有关系都应该深入检查。

问题的答案是 - ViewHolder 不必是内部类,您的问题是由于使用 ViewHolder 作为外部类时的无效代码实现引起的。

【讨论】:

我的viewHolder中有一个按钮实现了OnClickListener。当侦听器调用时,我需要单击哪个对象的按钮,因此我必须访问适配器的位置。但是,调用 getAdapterPosition() 会返回 -1,所以我崩溃了 IndexOutOfBounds 异常,可能您的项目中也会得到 -1。 :) @EgemenHamutçu 我肯定不会。要访问位置,请在 Adapter 中创建 getter 并将 Adapter 设置为 ViewHolder。【参考方案2】:

实际上,没有

首先你需要明白为什么我们需要 Inner 类?

我们确实需要内部类,我们希望只有特定的类才能具有此功能。就像我们有许多内部类,用于许多 ListenersButton onClick 等等。

所以我们使用内部类使事情变得私密、简短和简单

你可以把这个东西(ViewHolder)做成一个单独的类。但这不会是有效的,明确的(如果你再做一个类,它将为你的项目添加一个额外的类),并且是有效的方法。

【讨论】:

内部类也是“额外类”。 内部类实际上是非常糟糕的做法,因为它们“隐藏”在您的项目中。它更“干净”,建议使用“每个文件一个类”的原则。 请看这个:***.com/questions/11398122/… 内部类只有在你想直接访问父对象的变量和方法时才有用。这是不好的做法,因为它紧耦合两个类。如果您需要在两个类之间进行通信,您应该使用接口甚至更好,使用发布者-订阅者架构,这样您就可以在测试或生产等时轻松替换类。 我同意,在编程中我们有很多方法可以做一件事情。这有点相似,有些人喜欢多线程,有些人害怕多线程。这些事情因人而异。这就是为什么程序员将它们作为建议而不是规则。【参考方案3】:

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

在这里检查: https://***.com/a/29719632/6634292

你的问题很有趣;)

【讨论】:

以上是关于RecyclerView.ViewHolder 是不是总是必须是内部类?的主要内容,如果未能解决你的问题,请参考以下文章

获取特定位置的 ViewHolder - RecyclerView

Recyclerview ViewHolder中的TextView - OnClickListener

在“ListAdapter”或“RecyclerView.ViewHolder”做繁重的工作?

NestedScrollView内部的RecyclerView ViewHolder创建

尝试从空对象引用上的字段“android.view.View androidx.recyclerview.widget.RecyclerView$ViewHolder.itemView”读取

int android.support.v7.widget.RecyclerView$ViewHolder.mItemViewType' on a null.....