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!
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 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.
We update our entry widget to implement the required interface:
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:
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.