Use EnhanceScroller for listing items in Unity

This article is about the simple way of listing list item using EhancedScroller instead of ScrollView.

What is EnhancedScroller?

In simple terms advanced form of ScrollerView and extension plugin for the Unity UI's ScrollRect with additional features. The most notable and winning feature is the Recycling of gameObject avoiding garbage collection for better memory and processor performance. There are many other added features like snapping, looping and so on. You can learn better about it and its features in EnhancedScroller in Asset Store.

Why use EnhancedScroller?

Because it is easy to use. It is dynamic data-driven allowing us to build demo design without preparing any data.  It doesn't concern itself about the UI of the item listed in the list and we can use different types of items in a single list without any difficulty. so you can show a list of different item designs in a single list for your prototype using EnhnacedScroller before selecting one from them. EnhancedScroller allows the use of different sizes of items as well. So you are able to give any size to any item that you desire without any problem.

There are many features added to EnhanceScroller as shown in the picture below. You can add the required features to your list using these features from the editor. You can create an infinite loop of the list using Loop features and snap the items using Snapping. All these features are explained in detail in the Manual of the EnhancedScroller Plugin on the official site.

enah.PNG
EnhancedScroller's features visible from the editor

How to use EnhancedScroller?

For using EnhancedScroller in your project you will need to buy its plugin from the AssetStore. If you are considering if it is worth buying them I will say it is worth it. Because it will reduce your workload when working with a list for ScrollView. Now enough of the price taking, let's start by knowing how we to actually use the EnhancedScroller in your project.

Scripting Part:

First of all, you will need a base data class to hold the data of each item for the list. If you need many types of data to be shown in the list then you need to extend them from this base data class. By doing so we can use the list of this base data class and cast them to the required data class and use different data when required.

/// <summary>
/// Super simple data class to hold information for each cell.
/// </summary>
public class Data
{
    public string someText;
}
Base class for data of each list item

Secondly, you will need a script to control the enhancedScroller for your list. Let's create a script ListViewController with IEnhancedScrollerDelegate as its extension class and add the required references and variables as given below.

public class ListViewController : MonoBehaviour, IEnhancedScrollerDelegate
{
    /// <summary>
    /// Internal representation of our data. Note that the scroller will never see
    /// this, so it separates the data from the layout using MVC principles.
    /// </summary>
    private SmallList<Data> _data;

    /// <summary>
    /// This is our scroller we will be a delegate for
    /// </summary>
    public EnhancedScroller scroller;

    /// <summary>
    /// This will be the prefab of each cell in our scroller. Note that you can use more
    /// than one kind of cell, but this example just has the one type.
    /// </summary>
    public EnhancedScrollerCellView cellViewPrefab;


}
EnhancedScroller controlling script ListViewController

As you can see in the picture above we have the required following things:

  • _data -> Small List which is provided by the EnhancedScroller. You can replace it with an ordinary list as well. It is used for storing the data with which the list to be shown by EnhancedScroller will be updated.
  • scroller -> EnhancedScroller reference which will be dragged and dropped from the editor. It is the scroller we will delegate the controller script ListViewController for.
  • cellViewPrefab -> Prefab for each item on the list. This prefab is attached with a script to update the item and is extended from EnhancedScrollerCellView.

Note: the EnhancedScrollerCellView must to included as an extension class for the scripts that will be used as a prefab for the item of the list. The reason is that EnhancedScroller uses EnhancedScrollerCellView for handling the items of the list in the scene, not the script we create.

This script must be giving errors as we haven't included 3 mandatory methods for the interface class IEnhancedScrollerDelegate. Let's add them.

  1. Method for providing the total number of items the list of the EnhanceScroller will handle.

The total items to be shown will be the same number as per our `_data` of SmallList as it will hold the data we need to show in the list.

/// <summary>
/// This tells the scroller the number of cells that should have room allocated. This should be the length of your data array.
/// </summary>
/// <param name="scroller">The scroller that is requesting the data size</param>
/// <returns>The number of cells</returns>
public int GetNumberOfCells(EnhancedScroller scroller)
{
    // in this example, we just pass the number of our data elements
    return _data.Count;
}
Method to give the totalNumber of items to be shown in the list

2. Method for providing the size(generally height) of each index.

The EnhancedScroller ask for the size of the item while providing the index of item from the list. So if the items are all of the same sizes then provide a size of an item else provide the size of the corresponding item's size as per the given index by the EnhancedScroller.

/// <summary>
/// This tells the scroller what the size of a given cell will be. Cells can be any size and do not have
/// to be uniform. For vertical scrollers the cell size will be the height. For horizontal scrollers the
/// cell size will be the width.
/// </summary>
/// <param name="scroller">The scroller requesting the cell size</param>
/// <param name="dataIndex">The index of the data that the scroller is requesting</param>
/// <returns>The size of the cell</returns>
public float GetCellViewSize(EnhancedScroller scroller, int dataIndex)
{
    // in this example, even numbered cells are 30 pixels tall, odd numbered cells are 100 pixels tall
    return (dataIndex % 2 == 0 ? 30f : 100f);
}
Method to give the item size for the item of the list

Here we are providing 2 different sizes (alternating between odd and event data index ) to the item without checking for the data type as we will be only providing one type of data in the list.  You can provide only one size as well.

3. Method to provide prefab for each data.

The EnhancedScroller ask for the prefab to be used in the list by providing the dataIndex which correspond with the data index of the list of data _data we have. Hereby comparing the type of the dataType from our reference list we can provide different types of prefab for the item. But we are using a single itemPrefab so will provide just that.

/// <summary>
/// Gets the cell to be displayed. You can have numerous cell types, allowing variety in your list.
/// Some examples of this would be headers, footers, and other grouping cells.
/// </summary>
/// <param name="scroller">The scroller requesting the cell</param>
/// <param name="dataIndex">The index of the data that the scroller is requesting</param>
/// <param name="cellIndex">The index of the list. This will likely be different from the dataIndex if the scroller is looping</param>
/// <returns>The cell for the scroller to use</returns>
public EnhancedScrollerCellView GetCellView(EnhancedScroller scroller, int dataIndex, int cellIndex)
{
    // first, we get a cell from the scroller by passing a prefab.
    // if the scroller finds one it can recycle it will do so, otherwise
    // it will create a new cell.
    CellView cellView = scroller.GetCellView(cellViewPrefab) as CellView;

    // set the name of the game object to the cell's data index.
    // this is optional, but it helps up debug the objects in 
    // the scene hierarchy.
    cellView.name = "Cell " + dataIndex.ToString();

    // in this example, we just pass the data to our cell's view which will update its UI
    cellView.SetData(_data[dataIndex]);

    // return the cell to the scroller
    return cellView;
}
Method to give the prefab for the item of the respective index of the item in list

Note: The update of the items in each item is done here as shown in line number 22 in the above picture. You can customize it to your preferences as currently, we are only providing only the data to the item which correspond to the index of the dataList.

These three are the main methods that are provided by EnhanceScroller for getting the information it requires for controlling the list items. Now let's do another main thing we need to do for this controlling script to start working.

First, we need to provide the controller script `ListViewContrller` as the delegate of the EnhanceScroller `scroller` so the EnahncedScroller use the correct script to control the listItem.

/// <summary>
/// Be sure to set up your references to the scroller after the Awake function. The 
/// scroller does some internal configuration in its own Awake function. If you need to
/// do this in the Awake function, you can set up the script order through the Unity editor.
/// In this case, be sure to set the EnhancedScroller's script before your delegate.
/// In this example, we are calling our initializations in the delegate's Start function,
/// but it could have been done later, perhaps in the Update function.
/// </summary>
void Start()
{
    // tell the scroller that this script will be its delegate
    scroller.Delegate = this;

    // load demo data
    LoadData();
}
Update the delegate reference for the scroller

After updating the delegate of the EnahancedScroller load the data to be loaded to the list reference `_data` and Reload the EnhanceScroller method as shown in the picture below.

/// <summary>
/// Populates the data with a small set of records
/// </summary>
private void LoadData()
{
    // set up some simple data
    _data = new SmallList<Data>();

    _data.Add(new Data() {someText = "A"});
    _data.Add(new Data() {someText = "B"});
    _data.Add(new Data() {someText = "C"});

    // tell the scroller to reload now that we have the data
    scroller.ReloadData();
}
Load data to list and reload the EnhanceScroller

The control script is completed so let's create a script `CellView` for the prefab item for the list as shown below.

/// <summary>
/// This is the base class for the different cell types. We use a base class
/// to make calling SetData easier in the demo script.
/// </summary>
public class CellView : EnhancedScrollerCellView
{
    /// <summary>
    /// Internal reference to our base data class
    /// </summary>
    protected Data _data;

    /// <summary>
    /// Text to show the provided message in the data
    /// </summary>
    public Text SomeTextText; 

    /// <summary>
    /// Sets the data for the cell view. Note that the base data class is passed in,
    /// but through polymorphism we will actually pass the inherited data classes
    /// </summary>
    /// <param name="data"></param>
    public virtual void SetData(Data data)
    {
        _data = data;

        if (_data.someText.IsNullOrEmpty()) return;
        SomeTextText.text = _data.someText;
    }
}
Script for the prefab item to be shown in the list

CellView is the script that will be attached to the prefab gameObject and used as cellViewPrefab in ListViewController script.

Note: Be sure that the script used in the prefab for the list is extended from EnhancedScrollerCellView. if you forget this then enhance scroller will not identify that script and its gameObject.

Scene Part:

The scripting work is finished so let's work on the scene.

  1. Create an empty gameObject to hold the Controller script ListViewController as shown in the picture below.
E1.PNG
Creating a gameObject to add EnhancedScroller controlling script to it

2. Create a gameObject below the panel created and attach the EnhanceScroller script to it. Add image to it and mask and the most important thing is to give the size for this panel as per your requirement.

E2.PNG
Adding EnhancedScroller script to the gameObject

3. Create a temporary content gameobject Content: PlaceHolder like in the picture below. The reason for saying temporary is because the `EnhancedScroller` will create its own content gameobject when initiated.

content.PNG
Creating temporary content for making item reference inside it

4. Create an item that will be used as a prefab for the list items. In our case, we just created an image and gave it some height and width and created a text gameobject inside it. In Inspector as you can see in the picture below we have added CellView script and updated the reference which is only Text for now. CellIdentifier is used by the EnhancedScroller so b sure to add any word or character. Do not leave CellIdentifier empty. If left empty EnhancedScroller will give an error when loading.

1.jpg
Creating item and attaching the script to it

5. Return to EnhanceScroller attached panel and provide the temporary content Content: PlaceHolder to Content of ScrollRect in the inspector. This is done so that EnhancedScroller remove the temporary content when it is creating new content.

2.jpg
Updating the reference of the temporary content to ScrollRect

6. The prefab for an item must be used as a prefab so drag and drop the item to the asset folder.

3.jpg
Item drag and drop to Asset to make it a prefab

7. Give the reference of the item prefab from the asset not from the hierarchy.

4.jpg
Item reference drag and drop from Asset to ListViewController script in Inspector

Now you are ready to play the scene and use the enhanced Scroller. If you need to add space and padding among the items then give it as the given picture below.

final_ES_LI.jpg
Space and padding added to the EnhancedScroller

Now you should get the result as shown in the picture given below.

finalScene.PNG
The final result of the EnhancedScroller in the scene
This is all for the simple form of listing items in a list using EnhancedScroller. I hope this article will be helpful for others.