This blog post was originally posted at http://emi.gd/blog/scrolled-list/.
Hi! So, in the last post we learned how to create a scrollable list component, but we could only „hardcode” its elements. Today I’m gonna show you my proposal of a scrolled list implementation, that can be supplied by the elements list from the script.
The element script
First of all, we will create an abstract class for the elements – ScrolledListElement. It will be a generic class, which means that we have to provide an additional type when inheriting from it. This type will be naturally our data type. This class will have only two fields:
• DataCache – this will store our actual data,
• _transform – this will hold the transform cache for performance reasons.
All of the methods will be virtual. In the Awake method we will just cache the transform. The SetData method allows to attach this element to its new parent and also store the data. The whole class looks like this:
The desired usage would be to create a new class that inherits from ScrolledListElement and override at least SetData method – to fill all of the visual components (images, text) representing the element.
Loading the data
The ScrolledList component will also be a generic class, which requires providing two types – one is the data type and the other is an element type. We can also add a restriction that the element type must inherit from the Component class. The signature looks like this:
While creating several lists I noticed that it is really inconvenient to create an element prefab, delete it so that finally the lists starts empty, and then add it again when I want to make some visual improvements. That’s why I decided to leave the sample element as a child of the list and then treat it as a prefab in the list’s script. That involves looking for the element during the initialization phase, saving it and setting it as inactive. The only thing left to do in that phase is looking for the container game object in case it wasn’t set up in the Inspector. We also initialize the children list:
The most crucial is the LoadView method. It takes a list of elements as an argument and takes care of updating the children, then sets itself as active and sends an event OnViewLoaded – in case something should happen when all of the elements are created.
The next method we have to take care of is UpdateList. It invokes clearing method and AddElement method for every list item:
ClearPanel does what its name stands for – it clears present elements from the container game object. Firstly, it creates an actual list of the elements, then removes our “prefab” element from the list of items to be deleted, finally – deletes every item.
Last but not least – the AddElement method. It basically duplicates the sample element and invokes the SetData method from the ScrolledListElement class that we created earlier. This way the element gets attached to the container an can perform a proper initialization using provided data.
And that’s it! To use this ScrolledList component, for example to display a list of users, you should create UserList script that inherits from ScrolledList together with the UserListElement that inherits from the ScrolledListElement. Of course you also need a user data model. The LoadView method is virtual, so if you need to prepare your data primarily to displaying it, overriding it would be the way to go (e.g. if you wanted to sort or filter the data).
Pros and cons
Using this list is really convenient, it may seem like a lot work at first, but then creating new lists becomes much simplified.
There is still much room for improvements. At Tabasco we create and destroy such repetitive items using our ObjectPoolManager, but this is beyond the scope of this post. There could be also a mechanism implemented that would actually check for changes during the reload of the view instead of just simply deleting all items and adding listed ones.
The major drawback however is the performance. All of the game objects get created on LoadView, and all of them are present on the scene (although not visible). This causes visual imperfection while sliding though the list when there are many elements. For the simple usage it is acceptable though.
In one of the future posts I will present much more complicated and efficient solution – ScrolledListPooled, so stay tuned!
I created this scripts for the Kickerinho World implementation. They are provided under the MIT license and the original copyright belongs to TabascoInteractive.