Virtual List
Also known as the "infinite list," this list allows you to add large-scale data without significantly affecting performance.
MilListView
maintains an object pool of list item objects. During the Awake
phase, it determines the size of list items, then automatically reuses the list item objects and controllers through related calculations. In other words, not every piece of data has a dedicated list item object and controller bound to it. Instead, based on the portion of the list currently visible, the data for that portion is dynamically assigned to a limited number of list item objects and controllers, which then render them in the scene.
Virtual List Items
First, you need to implement a list item controller by extending the abstract class MilListViewItem
, which handles the appearance logic and interaction logic of list items.
Animation Settings
Override the list item's Default
state (optional, defaults to empty):
protected override IEnumerable<MilStateParameter> ConfigDefaultState()
=> MAni.States(() =>
...
);
Override the list item's Selected
state (optional, defaults to empty):
protected override IEnumerable<MilStateParameter> ConfigSelectedState()
=> MAni.States(() =>
...
);
If no UI animation is needed for the list item, both methods can simply return null
.
You can also configure the click animation of the list item by implementing the ConfigClickAnimation
method. The configured animation will play when the list item is clicked; if not needed, return null
.
protected override MilInstantAnimator ConfigClickAnimation()
=> ...;
Updating Appearance
For example, if the list item data is a string
, implement the logic:
public override void UpdateAppearance()
{
if (Binding is string str)
{
text.text = str;
}
}
Here, Binding
is the data currently bound to the list item, assigned by MilListView
.
Milease also provides a control function to adjust the appearance based on the current position of the list item. The parameter pos
ranges from , representing the relative position of the list item within the entire list.
For example, to make the text color most red at the center of the list:
public override void AdjustAppearance(float pos)
{
var p = 1f - Mathf.Abs(pos - 0.5f) / 0.5f;
text.color = Color.Lerp(Color.black, Color.red, p);
}
Event Handling
// Select the current list item
public override void OnSelect(PointerEventData eventData)
{
}
// Initialization event
protected override void OnInitialize()
{
}
// Termination event
protected override void OnTerminate()
{
}
The Awake
and OnDestroy
methods are occupied by MilListViewItem
. Instead, you can write related logic in the provided OnInitialize
and OnTerminate
events.
Other Properties
-
Index: The index of the data bound to the current list item within the
Items
ofMilListView
. -
ParentListView: The
MilListView
to which the current list item belongs. -
DefaultTransition: Duration of the transition to the
Default
state. -
HoverTransition: Duration of the transition to the
Hover
andSelected
states. -
OnSelectEvent: You can additionally bind methods here to be called when the list item is selected.
Setting Up the Virtual List
Since the virtual list needs to receive UI events, the raycast
of the UI it belongs to must be enabled to respond to clicks, scrolls, and other interactions.
You can add a MilListView
component on an Image, then create your list item objects as children of this Image (the root object of the list item must implement a concrete class derived from MilListViewItem
).
Then, drag your list item object into the ItemPrefab
field of the MilListView
.
Properties
Interaction part:
- Interactable: Whether to handle selection events. If disabled, clicking a list item will not trigger the
OnSelect
function. - Scrollable: Whether the list can be scrolled.
- Mouse Scroll Sensitivity: Scroll sensitivity (also applies to mobile scrolling sensitivity).
Appearance part:
- Vertical: Whether the list layout is vertical; otherwise, it is horizontal.
- Spacing: The spacing between list items.
- Start Padding: Distance from the first list item to the list boundary.
- End Padding: Distance from the last list item to the list boundary.
- Indentation: Indentation size of list items.
- Align: Alignment of list items.
Extended options:
- LoopList: Whether to enable the "looping list". When enabled, the last item connects to the first, allowing infinite scrolling.
- Scrollbar: The scrollbar component of the list.
Events:
- OnScrollDone: Triggered when scrolling ends.
Using the Virtual List
Data Operations
Add data to the virtual list:
listView.Add(obj);
The data can be of any type; it will be automatically assigned to a MilListViewItem
, i.e., the Binding
property you encounter when implementing MilListViewItem
.
Remove data from the virtual list:
listView.Remove(index);
// or
listView.Remove(obj);
Clear the data in the virtual list:
listView.Clear();
Update a specific item’s data:
// Replace the data at index with obj and update the item's appearance
listView.UpdateItem(index, obj);
Performing add, remove, or update operations on the list data within the OnSelect
event works properly. You can even delete the currently selected list item data.
Interaction
Select a specific list item:
// This will trigger the corresponding OnSelect event
listView.Select(index);
// If you want to trigger the OnSelect event, then
listView.Select(index, true);
Scroll to the top of the list:
listView.SlideToTop();
// To skip the scroll animation and jump instantly:
listView.SlideToTop(true);
Scroll to the bottom of the list:
listView.SlideToBottom();
// To skip the scroll animation and jump instantly:
listView.SlideToBottom(true);
Scroll to a specified position:
listView.SlideTo(position);
// To skip the scroll animation and jump instantly:
listView.SlideTo(position, true);
Get the position of a specified list item (for scrolling):
listView.GetItemPosition(index);
Others
Immediately refresh all list item appearances:
listView.RefreshItemAppearance();
Get the instances of currently displayed list items (MilListViewItem
):
listView.GetDisplayingItems();
Notes
- MilListView only supports list items with fixed size along the target dimension. For example, if your list is vertical, the height of list items must be fixed; if horizontal, the width must be fixed.
- MilListView determines the size of list items during the
Awake
phase for subsequent calculations. Therefore, you should ensure the item size is correct at that moment. - For looping lists, MilListView currently only works properly when the number of visible items is greater than the total number of list items.
- Because data is dynamically assigned to
MilListViewItem
, the same instance ofMilListViewItem
does not necessarily control the same data — theBinding
andIndex
of aMilListViewItem
instance can change dynamically.