ViewHolder不是内部类

时间:2015-03-16 01:05:00

标签: android android-recyclerview android-viewholder recycler-adapter

RecyclerView.ViewHolder可以不用作内部类吗? 这样做有什么问题吗?

我已经四处寻找,但没有找到任何文件!

1 个答案:

答案 0 :(得分:7)

实际上,我认为ViewHolder应该是静态嵌套类(介意静态!)或顶级类(实际上没有什么不同,只是类名将包含外部类名后跟$然后是内部类名。)

为什么我这么认为?当ViewHolder是适配器的非静态内部类时,它保留对适配器的引用。现在,当您调用RecyclerView.swapAdapter(newAdapter,false)(或者它是否为真?我不记得)时,新适配器将使用旧版本之前创建的ViewHolders。由于无法在这些持有者中取消/清除此类隐式引用,因此对第一个适配器的引用已泄漏且无法进行垃圾回收。这已经够糟了。

但是,就我而言,我遇到了与记忆无关的真正问题。我的适配器有一个选择模型&#39;保持位置到数据的映射,视图持有者在显示项目时会使用数据(例如,当选择模型表示选择位置17的项目时,当它在屏幕上绘制时,其字体颜色会更改)为用户标记它。它是通过从适配器访问选择模型字段来实现的,在Java中它意味着它使用对封闭适配器实例的隐式引用而不是访问其字段。现在,在swapAdapter之后,保留的ViewHolders仍在使用适配器的选择模型,并且UI被破坏,因为有些项目将显示为已选中,而在新模型中则不是。< / p>

基本上,这样的非静态内部类持有者不可能比创建它们的适配器寿命更长并且被另一个使用它来真正忘记旧的并使用新的适配器,因为没有办法清除那个隐式引用

有很多解决方案,其中一个是ViewHolder是静态嵌套类,只是在绑定时显式地为它提供引用,并在解除绑定时将其置空。我一直在为我的视图持有者使用顶级类,并明确引用了适配器,我认为这就是你要问的问题。请注意,持有者根本不需要对其适配器进行任何引用,因此您可能根本不需要设置适配器。

当然,我的问题源于我交换光标的事实;如果你不这样做,你可能没有注意到任何问题,但我认为最好注意它们。