【问题标题】:ViewHolder not as a inner classViewHolder 不是内部类
【发布时间】:2015-03-16 01:04:59
【问题描述】:

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

我已经四处搜索,但没有找到任何文档!

【问题讨论】:

标签: android android-viewholder android-recyclerview


【解决方案1】:

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

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

但是,就我而言,我遇到了与记忆无关的实际问题。 My adapter had a 'selection model' which kept position-to-data mapping and the view holder would use the data when it shown the item (like for instance, when the selection model said the item at position 17 is selected, when it was在屏幕上绘制,它的字体颜色会改变)为用户标记它。它只是通过从适配器访问选择模型字段来实现的,这在 Java 中意味着它使用对封闭适配器实例的隐式引用,而不是访问其字段。现在,在 swapAdapter 之后,保留的 ViewHolders 仍在使用 适配器的选择模型,并且 UI 已损坏,因为某些项目会显示为已选择,而在新模型中却没有。

本质上,这样的非静态内部类持有者不可能真正忘记旧的适配器并使用新的适配器,因为没有办法清除隐式引用.

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

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2018-02-05
    • 1970-01-01
    • 1970-01-01
    • 2019-01-07
    • 2012-11-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多