Hey everyone, I’m working on a basic inventory system and was wondering if there is a way to add an item to the top of a list-view? I’m using a TileView for the widget and all functions work however when adding an item it just appends it to the end of the list. I want to add the item to the start of the list. How may I achieve this? Appreciate any help, any at all!
EDIT: Here is a video of what’s happening, and what I want:
For e.g, I want the helm to be displayed on top of the ListView when added into it again. I digged around in the UE4 docs but I couldn’t figure a way out.
It’s not there - - undocumented afaik. Never seen it covered anywhere. And since ordering widgets containers is such a nuisance, this should come in handy.
Hey mate, thanks for reaching out! I tried this just now and it seemed to crash the engine but I think I messed something up XD. So, here is the current code I use:
Since I’m still a newbie the inventory system is pretty basic and at start, I just add some stuff to the inventory using this event, so I don’t know if I can change it to this without breaking a lot of code I made… I really don’t know how I can manage to do this
Still appreciate the help tho! I will keep on trying this method.
EDIT: I believe I have to somehow get an Index input for the event “AddItem” and use it for placement, but no clue how!
Yeah I’m still pretty new to the engine so I really appreciate your time, however I couldn’t figure out how that code works, but thanks again mate, I will go over it and try to get it working, and if I do, I’ll let you know here. Cheers!
Alright, that seems to work! However, now ANY item that gets added back to inventory goes to the top of the list! So for e.g the necklace which is just below the helm goes above the helm when I equip it, is there any way I can control this?
I don’t understand why they added Get Index for Item but not Set Index for Item function! Yikes
When it comes to UI animation, for example, playing an insert animation for a new item, refilling the whole array won’t help.
You can just inherit from the listview class and write your own AddItem function. Basically copying the original code but replace that “Add” with “Insert”. This works fine in my project.
void UAFPListView::AddItemAt(UObject* Item, int32 Index)
{
if (Item == nullptr)
{
FFrame::KismetExecutionMessage(TEXT("Cannot add null item into ListView."), ELogVerbosity::Warning, "NullListViewItem");
return;
}
if (ListItems.Contains(Item))
{
FFrame::KismetExecutionMessage(TEXT("Cannot add duplicate item into ListView."), ELogVerbosity::Warning, "DuplicateListViewItem");
return;
}
ListItems.Insert(Item, Index); // rather than ListItems.Add()
const TArray<UObject*> Added = { Item };
const TArray<UObject*> Removed;
OnItemsChanged(Added, Removed);
RequestRefresh();
}
Hi, doesn’t that defeat the purpose of list view? If you have thousands of elements, you’ll have to bring them all in memory when constructing the temporary array, right?
Afaik, the objects are already instantiated. From now on it’s up to you to use soft references and handle (or not) asset loading as the list view generates widgets.
Ask the panel how long its list is run-time. What do you get?
Can’t recall if that extra array is necessary. For some reason I though it was, normally this would be a local variable anyway, ofc.
Yeah, maybe that’d be more efficient. As you mentioned handling asset loading and soft references, the whole point of list view would be to do that work for you, as I understand. Wish I knew how they actually work, or how to properly implement one. Again, official documentation severely lacking.
That’s not its job, sadly. Its job is to instantiate only the widgets the user can see, and release the ones we’re not looking at. What, when & how the dev wishes to load stuff is up to them.
But the docs are scarce, true that. If the following is not clear enough, do start a new thread.
an object with a soft ref - think of it as of a path to an asset:
Pretty lightweight stuff, actually. Ideally you do it once and keep the objects alive - that’s the whole point of having (lots of) RAM. Unused RAM is wasted RAM.
list view widgets pull paths out of the objects, and load assets on the fly - only when needed, when the widget is showing & the asset is in an unloaded state:
The Garbage Collection will take care of releasing assets from memory () providing they’re not referenced anywhere else - and that’s the List View’s job. Throw the widget on the GC’s heap.
That’s the BPs way at least, you can sneak in a manual Collect Garbage yourself if necessary.