Search code examples
algorithmuser-interfacescrollvirtualization

UI virtualization implementation details. How to implement it?


I know that several frameworks implement UI virtualization, like C# WPF, Qt QML and Aurelia JS.

I understood the basic idea of how virtualization works and how items are recycled during scrolling.

Given that i struggle to understand:

  • how can the viewport know which item need to be drawed given it's offset?
  • how can the viewport calculate it's real dimensions if the items could have different heights?

The real problem is variable heights (or widths) in the item painted during scrolling. In fact if the height of the painted controls is fixed everything is simple:

  • Content size is numItems*itemHeight (or numItems * itemWidth)
  • The first item painted in the view is calculate by ViewPortOffset / ItemHeight. For example if the Viewport has size 100x100 and it's current offset is 200 and itemHeight is 10 than the first item to be painted is item 20.

Are there any kind of resources or blogs for learning how to solve this problem with variable heights/widths


Solution

  • In my Sciter Engine I have an example of virtual scrollable list of items having variable heights:

    enter image description here

    with or without kinetic (animated) scroll support.

    Implementation is quite straightforward, check {sciter-sdk}/samples/ideas/virtual-list/vertical.htm demo and tapev.tis implementation.

    It uses sliding yet fixed buffer of DOM elements - at any given moment of time only const BUFFER_SIZE = 20; of elements are loaded into the view. And so it can be used to scroll over recordsets of unlimited length.

    It works pretty well but with one obvious limitation - no scrollbar. To be precise: no scrollbar that reflects items/content dimensions as the whole recordset is not available at the rendering time. But you can have scrollbar that approximates that - e.g. scrollbar slider size reflects number of items seen and its position - index of first item in the view.