【问题标题】:RecyclerView onBindViewHolder is called even before view is visible甚至在视图可见之前调用 RecyclerView onBindViewHolder
【发布时间】:2016-08-19 20:22:47
【问题描述】:

是否期望在视图可见之前调用 onBindViewHolder ?我需要记录用户看到的视图/索引,但找不到好方法。现在,我计划监听滚动事件并继续检查第一个和最后一个可见视图,并使用范围来检测哪些视图是可见的。这些计算将在每个滚动事件上完成 - 即使经过一些优化,这似乎也是一个坏主意。

我使用的是 LinearLayoutManager,没有预缓存。

【问题讨论】:

  • 所以findFirstVisibleItemPosition / findLastVisibleItemPosition 应该是你的朋友
  • 我知道方法。我正在寻找更好的选择。
  • 他们怎么了?
  • 如帖子中所述,first/last* 方法没有任何问题。问题是这些方法会在每次滚动时触发(而不是一扔)。
  • 它在滚动和投掷时都被调用

标签: android android-recyclerview


【解决方案1】:

onBindViewHolder() 实际上总是在进入查看之前调用,以便 ViewHolder 在出现时处于正确状态。这可能是一个“足够好”的解决方案,因为 ViewHolder 通常仅在它刚刚超出范围时才被绑定。

我能想到的另一个解决方案可能是简单地跟踪滚动的距离。假设每个视图在屏幕上的大小相同,您可以跟踪滚动的距离。如果dy > viewHeight 则您可以将“查看的索引”计数器加一。想法是您始终从索引 0 开始,因此索引0 - n 已经被立即查看。然后,当用户向下滚动时,它将是0 - n+10 - n+2 等等。这种计算会比在每次滚动时使用findFirstVisibleItemPosition() 快得多。

您还必须考虑到任何对setPosition 的调用都会产生影响。这使您可以在 RecyclerView 中跳转,因此每次执行此操作时都必须重新计算。这就是findFirstVisibleItemPosition 调用会派上用场的地方。 (无论如何,您都需要这样做,因为不会调用滚动侦听器)。

此外,如果您在删除索引时执行任何过滤,这也会对结果产生影响,需要加以考虑。

【讨论】:

  • 视图即将显示时不应该调用 onBindViewHolder() 吗?所以在 findLastVisibleItemPosition()+1 项目上调用是有意义的。但我观察到 onBindViewHolder 需要更多索引。我的视图有不同的高度,但它们都至少 300dp 高。
  • 是的。它是,但你正在寻找可见的。用户可以滚动到第 15 项(共 100 项)并向后滚动。第 16 项将被绑定但不显示。
  • 实际上,您可以说“最高界限 - 1”是可见的,但不能保证最高将是“最后可见 + 1”。它不在合同。他们可以将实现更改为“最后可见 + 3”,而您将一无所获(尽管这不太可能)。
  • 这是有道理的。我想我不能使用 onBind 来满足我的要求。
猜你喜欢
  • 1970-01-01
  • 2019-05-18
  • 2020-03-01
  • 2019-01-15
  • 1970-01-01
  • 1970-01-01
  • 2016-02-11
  • 2015-10-19
  • 1970-01-01
相关资源
最近更新 更多