UI虚拟化实现细节。如何实现它?

时间:2016-06-08 17:09:44

标签: algorithm user-interface scroll virtualization

我知道有几个框架实现了UI虚拟化,比如C#WPF,Qt QML和Aurelia JS。

我理解虚拟化的工作原理以及滚动过程中如何回收项目的基本思路。

鉴于我很难理解:

  • 视口如何知道哪个项目需要绘制,因为它的偏移?
  • 如果项目可能具有不同的高度,视口如何计算它的真实尺寸?

真正的问题是在滚动期间绘制的项目中的可变高度(或宽度)。实际上,如果绘制的控件的高度是固定的,那么一切都很简单:

  • 内容大小为numItems * itemHeight(或numItems * itemWidth)
  • 视图中绘制的第一个项目由ViewPortOffset / ItemHeight计算。例如,如果视口的大小为100x100且当前偏移量为200且itemHeight为10,则第一个要绘制的项目为项目20.

是否有任何资源或博客可供学习如何使用可变高度/宽度来解决此问题

2 个答案:

答案 0 :(得分:2)

在我的Sciter Engine中,我有一个虚拟可滚动列表,其中包含可变高度的项目:

enter image description here

有或没有动态(动画)滚动支持。

实施非常简单,请查看{sciter-sdk} /samples/ideas/virtual-list/vertical.htm演示和tapev.tis implementation

它使用DOM元素的滑动但固定的缓冲区 - 在任何给定的时刻,只有const BUFFER_SIZE = 20;个元素被加载到视图中。因此它可用于滚动无限长度的记录集。

它工作得很好,但有一个明显的限制 - 没有滚动条。确切地说:没有反映项目/内容维度的滚动条,因为整个记录集在呈现时不可用。但是你可以使滚动条接近那个 - 例如滚动条滑块大小反映了所看到的项目数及其位置 - 视图中第一个项目的索引。

答案 1 :(得分:0)

我相信大多数UI虚拟化依赖于具有相同大小的项目。

如果你需要你的物体具有不可预测的尺寸而不是我想到的一个想法。对于每个元素存储的某处,它开始的偏移量(px位置)。我认为最好的是一系列职位。

例如,您有垂直视图,其中10个对象的大小为10x10,20x20,...,100x100。他们将从以下职位开始:0,10,30,60 ...... 我们假设您的观看次数从y1 = 15显示为y2 = 40。现在,您需要渲染从位置开始大于y1且小于y2的所有对象,并且还要从每一侧渲染一个对象。所以你需要渲染第二个,第三个和第四个对象。

当然,如何存储起始位置以及用于查找值的算法非常重要。如果您需要视图包含大量项目,那么您还应该考虑将要实现算法的语言。