I have a scrollbar with a horizontal box placed inside it. Inside the horizontal box, there are 3 list views. My goal is to scroll the 3 list views together when the user is scrolling with the mouse, this way I can show a list of images which are not uniformly sized in 3 columns. This works just fine, however, the performance is really bad because the list views are not releasing/generating the entires as the scrolling happens, but instead, it is showing ALL of the entries at once. My question is, why does it work like this, why doesn’t it generate widgets only for those which are visible on the screen, why does it generate it for all of them? If I place the listview outside of the scrollbar, it works properly.
List views in Unreal Engine is most likely generating all of their entries at once because that’s how they were designed. They generate all the widgets for their entries up front, because the widgets are often used for sorting, filtering, and searching, and those operations require access to all the entries.
If performance is an issue, one possible solution is to use a different widget that only generates the entries that are visible on the screen, such as a ScrollBox or a TileView. You could also try to limit the number of entries that are generated by using a combination of lazy loading and/or pagination.
Thanks for the input. As far as I know, the purpose of listviews is exactly as you described. You add up to thousands of entries to the list as UObjects, but they only generate a widget for those which are visible on screen. And it works as expected until you place the list view as a child of a scrollbox.
Took some fiddling, trial & error but I got it to work - to an extent. And yes, it seems buggy as described, and it is not in the bug DB - or I could not find it there.
But I do not think this is a bug in the first place. A scroll box utilises the size of the underlying widget. How would you determine the size of the list view where items differ in size? You’d need to generate all entries first and lay them out. If there is no desired size, there can be no consistent scrolling mechanics.
I guess it’s a rare interaction hardly anyone would ever run into since the list view has its own scroll bar already. So, I got this - hoping it’s close to the description:
I turned those 3 list views into a user widget first, and only then wrapped them with a scroll box. The SB has an actual size to work with.
Perhaps you can make it work the way you need with some padding and dummy widgets serving as offsets for the scroll bar.
There is 150 widgets in each list view, for a 450 total and up to 50 are being kept alive for a widget this size - as indicated by the number on the right. The list views actually keep more cached widgets than they display. But if you crank the total to several thousands, still only a handful will be kept alive, probably no more than 50. The more entries you have, the more efficient it becomes.
I am attaching a video so you guys can see what is the goal. I am listing images in a catalog, the images have different sizes. I have 3 list views placed inside a horizontal box, the horizontal box is placed inside the scrollbox. The scrolling is turned off for the list views, but enabled for the scrollbox. This way when I am scrolling, all 3 list views are scrolled and the images of the 3 list view are moving together. By default, the list view is virtualized, which means it is generating only as many widgets as visible on the screen. So if only 5 widgets fit the screen, it will only generate 5 of them, even if the list view have 1000 entries. The problem is, once I place them inside the scrollbox, it is generating all of the widgets and never releases them, unless I remove the items from the list.
The goal would be to have a list capable of handling uniform width, but non-uniform height items. My other option would be tile views, but it would mean either squeezing/stretching the images so that they fit into the tiles and would not look so pleasent as the current solution. The problem with the current solution is that it fills up the memory because of all the images and widgets being always loaded.
See the video:
I tried removing the scrollbox and enabling the scrolling for the list views, and added an event for the scrolling so that when one list is scrolled, I can scroll the other two too. The problem is that since the lists have different lengths because of different image sizes, setting the scroll offset to the same as the scrolled one does not work and the 3 lists move independently this way.
I have solved this issue by setting the padding for the last item of each list so that the list size is the same with the padding for each of them. For the scrolling, I added a delegate for the OnListViewScrolledInternal one, and when one list is scrolled, I am scrolling the other one too. I am calculating the scroll offset value by iterating through the images to calculate the maximal list length, and then when I scroll a list, I interpolate it to the other lists too by using its scroll offset. All works fine now, except in some cases, the list view refuses the scroll, even though there are some items left still. Any idea what may cause this? It gets stuck at certain points, and the scrollbar stretches too. If I scroll through another listview, I can scroll through this problematic point, but after that, it gets stuck again if I try to scroll with mouse.