Filling a vertical box with widgets is super common in UMG. But depending
on the complexity or number of widgets, you might start noticing frame skips
when the list is first populated. UListView, and its siblings UTileView and
UTreeView are the solution to this!
Naive Implementation
The simplest way to populate a list of items is to instantiate a widget for
every item in the list. If your list is less than 10 or so elements, this is
totally fine.
However if there are many more elements in the list than would be displayed
on-screen, then it's worth considering UListView.
Let's see how our basic example works before diving into UListView.
UListView Implementation
UListView is Unreal's way of using a re-usable pool of widgets.
It only creates as many widgets as are needed to fill the on-screen list areal.
As a widget scrolls out of view, it is removed and added to a pool of available
widgets to be re-used. So even if your list 100+ items long, it will only ever
have a few widgets instantiated at any one time.
So how do we use it?
Make the widget that will be showing each individual item implement the IUserObjectListEntry interface.
Use SetListItems to provide UObject data to the UListView instance.
Done!
We update our entry widget to implement the required interface:
BUIInventoryEntry
BUIInventoryPanel
Our naive implementation's UVerticalBox is replaced with UListView. We also
no longer need a TSubclassOf<T> property for our Entry. Instead we set that
directly in the InventoryListView properties (see screenshot below).
We also need to update our Widget Blueprint so that our new List View widget
knows what Widget Blueprint to use when creating the list entries:
Done!
That's it, we're done, now we can have a list with hundreds of items and only
ever have a few widgets instantiated at a time!
Tree View and Item View
There are similar widgets called Item View that presents widgets in a grid, and
Tree View that allows widgets to be expanded and collapsed. The C++
implementation is basically identical. They have the same SetListItems
function, there are just different options for how each entry is presented.