Binding data to ListView

TL;DR

How do I feed the data into the generated child widgets?

What I’ve tried / done so far:

(I refer to this widget, if you’re wondering)

264046-widgets01.png

I have a widget called item (Will be the children in the List View) that needs to display two data attributes from my list.

“Binding” data to a List View widget seems pretty straightforward, you just call set List Items and you’re supposedly ready to go:

264047-widgets02.png

But the problem is that the list view does not know how to translate the data from the list into the widgets. Even tho that item implements User List Entry or User Object List Entry (Tested both) I’ve found no way to tell the item to
widget to translate the data, or even receive it.

Disclaimer: I already know that you can make a scrollable list by placing widgets, this is about List View widget.

You don’t add the widgets to the list directly, instead you create an Object blueprint which will contain the data you want. And when adding an item to the list you construct that object and add it. For it to use your widget, set the Entry Widget Class, to your widget, in the details panel of the List View

So, make a new Blueprint class, pick Object as its parent class (not Actor). In this class add all the variables you need. Set them as Editable and Exposed On Spawn:

264048-lv1.jpg

Then, in your widget which will be the entry, make sure you have implemented the User Object List Entry interface. In the event graph, right click and find the “Event On List Item Object Set”. The object passed in this event is the one you created above, but you’ll need to cast it to your class first to access the variables. You can then use those variables to set the text in your widget or whatever you want to do with the data. Like this for example:

And finally, to actually add entries you use Construct Object, construct an object of the the same class you created above, here you can plug in whatever values you want, and then use Add Item to add it your list. The List handles creating the widgets themselves, it just needs the data.

You could probably iterate through your inventory items and construct add the data objects like I did here:

I’m using tile view but it’s the same idea. I have found the selection bit of tile views are a bit buggy though, at least in 4.21.

This is the best explanation of usage of list view.Thanks so much…

Does anyone know how to reflect any updates made to the objects create like above to the widgets using them?

Yes there is indeed! I struggled with updating the list for a while and finally stumbled across this easy to miss function: Set List Items. It sets the list to pull from an array of data objects instead of adding them directly. Simply update the data variable on the object in the array and call the Regenerate All Entries function on the list view. It updates the list view! Another method I got working is calling custom events on the object and passing params to update individual fields. The way to do this is to pass the ref of the list item widget back to the data object by setting a public variable on the data object during Event On List Item Object Set. Then use the ref in the variable to edit any fields or bound variables you made public in the list view widget. It is a bit complicated but it’s another option.

Thanks! This is exactly what I did as well.

Cool! In the end though I had to abandon the list view and use a scroll box instead. Implemented game pad navigation of the list (to allow the player to use D-Pad up/down) by way of button events and some simple math. It works as expected but the list view Scroll Index Into View function offers no scrolling animation and always puts the index at center, creating a harsh and unnatural scrolling experience, especially when using press-and-hold navigation acceleration. The scroll box uses animated smooth scrolling and keeps the selected item at the edge of the list as seems customary. Maybe the list view is best suited for mouse-only applications.

EDIT: I learned the scroll box has a hard limit nearabout 200 items beyond which FPS loss occurs for the entire game whether the scroll box is visible or not. Yikes! I need potentially longer lists for my looter shooter so I returned to the list view. Not yet defeated I painstakingly figured out complex blueprints to create fake scrolling by means of maintaining only the list items visible on the screen, refilling the list view upon each scroll event and playing translation animations inside the list view widget to trick the eye into believing the list scrolled. And it works fluidly! No FPS loss. We can have it all! :smiley:

Please excuse my curiosity, what did you end up using? A listview but with “custom scrolling”? The “maintaining only the list items visible on the screen” sounds like a workaround for the scrollview limitation, while the custom scrolling sounds like a workaround for the listview.

I ended up using the listview. It may seem a bit strange but “maintaining only the list items visible on the screen” pertains to the list view. The scrollbox workaround would require managing a set of re-usable widgets and trying to manipulate them back and forth to create fake scrolling. Blueprints do not allow inserting widgets in a specific position so it gets too tricky for me and I am not skilled at C++ yet. The listview’s built-in management of re-usable widgets makes it possible with blueprints. I build two object arrays: the master list and the currently visible list. The list view displays the currently visible array. When it is time to scroll up or down the blueprint determines what the new currently visible list should be, updates the currently visible array and calls Set List Items on the listview passing in the currently visible array. Immediately next I call an animation on the widget to translate the listview in either the positive or negative Y, depending on the direction of the scroll. By wrapping the listview with a vertical box and setting the vertical box and the listview to clip to bounds it appears to scroll like a scrollbox. To keep the scroll bar from showing (in case the last item is partially visible) set the list view slot to Auto, ||, = and the vertical box slot to Fill 1.0, ||, =. I use little arrows at the top and bottom of the list to indicate if scrolling is possible. The blueprint is somewhat massive and seems complicated but executes super fast. The result is the memory-friendly listview combined with faked animated scrollbox scrolling. Best of both worlds possibly.

Thanks! I appreciate the explanation. I’m currently doing something very similar, swapping two arrays on a listview. Cheers.

Thank you sooo much Mosel3y!
I was starting to loose my sanity…

THANK YOU! This instantly unlocked the mystery around this for me.

Another option is Set the struct after adding the object of widget reference of it’s property.