Notification List
A scrollable notification feed with unread-count badges and an elastic, swipe-to-load-more list.
Overview
This example builds a mobile-style notification feed that grows on demand. It pairs an elastic, overscrolling list with an unread-count badge and a pill action button, showing how to drive a live “load more” flow and keep an unread counter in sync as items are added and cleared.
Controls Featured
- Elastic List View — hosts the notification rows with iOS-style elastic overscroll and raises a swipe-up “load more” request that the demo answers by appending three more items
- Notification Badge — sits at the top-right of the card and tracks the unread count; tapping it marks everything read and hides the badge
- Pill Button — the gradient “Add Notification” button that appends one row and bumps the unread count
Scene Setup
- Create a new Unity scene.
- Add an empty GameObject and attach a
UIDocumentcomponent. - Create a
PanelSettingsasset configured for portrait mobile (Scale With Screen Size, reference resolution 1080 × 1920, Match → Height) and assign it to theUIDocument. - Add the
NotificationListDemoMonoBehaviour (found inExamples~/NotificationList/) to the same GameObject. It callsGetComponent<UIDocument>()inStart, so no manual reference assignment is needed. - Press Play.
A ready-made scene is provided in the folder. A UXML-authored variant (
NotificationListUxmlBinder+NotificationListUxmlView.uxml) builds the same screen declaratively and queries the controls by name.
What to Expect
A card titled “Notifications” appears with a small unread badge anchored to its top-right corner. The list is seeded with four items, each a coloured accent stripe beside a message and a “Just now” timestamp.
- Tapping Add Notification appends a new randomly generated row and increments the badge count (the display clamps to
99+). - Tapping the badge marks all notifications read: the count resets to zero and the badge hides itself.
- When the content fits the card, the list still gives a finger-following bounce; when it overflows it scrolls with elastic overscroll.
- Swiping up past the bottom edge requests more items: the demo simulates a short fetch (about 700 ms), shows the load-more spinner, then appends three more rows. Swipe input is unreliable in the editor, so use the Add Notification button there and test the swipe-to-load on device.
Key Code Patterns
Enabling elasticity and load-more, then servicing the request by appending a batch between BeginLoadMore and EndLoadMore:
listView = UIToolkitExtensions.CreateVisualElement<ElasticListView>(card, "notificationListDemo__list");
listView.EmptyStateText = "You're all caught up.";
listView.EnableTouchElasticity(0.12f);
listView.EnableLoadMore();
listView.LoadMoreRequested += OnLoadMoreRequested;
private void OnLoadMoreRequested()
{
if (loadingMore) return;
loadingMore = true;
listView.BeginLoadMore();
listView.schedule.Execute(() =>
{
for (int i = 0; i < LoadMoreBatch; i++)
{
listView.AddItem(CreateNotificationItem(RandomMessage()));
}
listView.EndLoadMore();
loadingMore = false;
}).StartingIn(SimulatedFetchMs);
}
Keeping the badge in sync — add bumps the count, tapping it clears:
addButton.Clicked += OnAddClicked;
badge.RegisterCallback<ClickEvent>(_ => MarkAllRead());
private void OnAddClicked()
{
listView.AddItem(CreateNotificationItem(RandomMessage()));
unreadCount++;
badge.SetCount(unreadCount);
}
private void MarkAllRead()
{
unreadCount = 0;
badge.SetCount(0);
}