【发布时间】:2018-04-20 12:05:00
【问题描述】:
在InfiniteLoader 内部,我有一个List,它的rowRenderer 回调创建了一个由CellMeasurer 包装的<div>(我也为此使用了缓存)。行的大小可以变化很大,但这种设置非常适合滚动。
但是,每行中的元素可以根据用户输入动态改变高度。在这些情况下,我会调用:
cellMeasurerCache.clear(rowIndex, 0);
this._listRef.recomputeRowHeights(rowIndex);
但在某些情况下,这会导致行跳动——这是因为 top 的值计算不正确。例如,我正在显示一个文档,其中在List 中呈现了以下行:
rowIdx height top
3 668px 420px
4 8547 1088
5 2420 9635
然后第 4 行的高度略有增加(~50px)。使用rowIndex == 4 运行上述代码后,我看到以下行:
rowIdx height top
5 2420px 3088px
6 1156 5508
7 4718 6664
8 1050 11382
如您所见,第 5 行现在有一个不正确的 top 值,导致行跳来跳去。我假设没有正确测量第 4 行的高度。
怎么了?
2017 年 11 月 8 日更新: 似乎调用 cellMeasurerCache.clear(rowIndex, 0) 会将该行的高度替换为 estimatedRowSize 的值,这是非常不同的。它似乎没有重新测量,与文档所说的相反。
CellMeasurer._maybeMeasureCell() 在获得默认高度后不会为第 4 行调用。我的rowRenderer 回调(围绕我的内容创建CellMeasurer)仅从第 5 行开始调用。因此,代码已决定显示哪些行,而行 4 的默认高度要小得多,而不是事先计算。
【问题讨论】:
-
"看来调用
cellMeasurerCache.clear(rowIndex, 0)会将该行的高度替换为estimatedRowSize的值,这是非常不同的。它似乎没有重新测量,与文档相反说。”这是对的。此方法清除缓存的测量值,以便在下次渲染单元时重新测量。随后对list.recomputeRowHeights的调用将重新渲染,从而触发测量。至少它应该是这样工作的。如果这没有发生,听起来可能有错误。 -
对,我没看到。调用
list.recomputeRowHeights时应该在哪里调用CellMeasurer?在单步执行代码时,我只看到它使用了默认值。 -
我不久前写了这个应用程序作为概念证明:tweets.now.sh
-
也许对你有帮助?