8.6 Released with πŸ₯½ visionOS support and more!
Check it out

<ListView> is a UI component that renders items in a vertically scrolling list, the template for the items can be defined via itemTemplate (or multiple templates via itemTemplates - more on that below). The ListView only renders the visible items, as the user scrolls, new items render by reusing a no-longer-visible item's viewβ€”this is usually referred to as view-recycling.


For additional features and improved performance in certain scenarios, consider using an alternative implementation like the CollectionView from the community.

<ListView items="{{ items }}">
    <!-- The item template can only have a single root element -->
    <GridLayout padding="16" columns="20, *">
      <ContentView width="20" height="20" borderRadius="20" backgroundColor="#65adf1" />
      <Label text="{{ title }}" col="1" textWrap="true" marginLeft="8" />
const items = Array.from({ length: 100 }).map((_, i) => ({
  title: `Item ${i}`,

Examples ​

ListView with multiple itemTemplates ​

Individual items can be rendered using a different template. For example, let's say our items can either be headings or items. In that case, we can define a template for them, and pass in an itemTemplateSelector function that will get called before rendering an item.

<ListView items="{{ items }}" itemTemplateSelector="{{ itemTemplateSelector }}">
    <template key="heading">
      <!-- template for headings -->
    <template key="item">
      <!-- template for items -->
// example item definition
type ItemType = {
  title: string
  type: 'heading' | 'item'

// called for each item in the list before rendering
function itemTemplateSelector(
  item: ItemType,
  index: number,
  items: Array<ItemType>
) {
  return item.type === 'heading' ? 'heading' : 'item'

Props ​

items ​

items: Array | ObservableArray

Gets or set the items of the ListView.

For static lists using an Array is fine, however for dynamically changed arrays it's recommended to use an ObservableArray to optimize re-rendering performance.

See ObservableArray.

itemTemplateSelector ​

itemTemplateSelector: (
  item: T,
  index: number,
  items: Array | ObservableArray
) => string

A function to be called when selecting the template for the item.

itemTemplate ​

itemTemplate: KeyedTemplate

Gets or sets the default item template.

Note: this is usually set by the framwork (eg. ListView.itemTemplate via xml).

See KeyedTemplate.

itemTemplates ​

itemTemplates: KeyedTemplate[]

Gets or sets the available itemTemplates.

Note: this is usually set by the framwork (eg. ListView.itemTemplates via xml).

See KeyedTemplate.

separatorColor ​

separatorColor: Color

Gets or sets the color of the line separating each item.


Set the separatorColor to transparent to hide it, or use your own borders.

See Color.

rowHeight ​

rowHeight: number

Gets or sets the row height of the ListView. Useful when your items have a fixed height, as the required calculations are greatly simplified and the rendering can be faster.

iosEstimatedRowHeight ​

Gets or sets the estimated height of rows in the ListView. Default value: 44px

...Inherited ​

For additional inherited properties, refer to the API Reference.

Methods ​

refresh() ​


Forces the ListView to reload all its items.

scrollToIndex() ​

listView.scrollToIndex(index: number)

Scrolls the item with the specified index into view.

scrollToIndexAnimated() ​

listView.scrollToIndexAnimated(index: number)

Scrolls the item with the specified index into view with animation.

isItemAtIndexVisible() ​

listView.isItemAtIndexVisible(index: number) // boolean

Checks if the item with the specified index is visible.

Events ​

itemTap ​

on('itemTap', (args: ItemEventData) => {
  const listView = args.object as ListView
  console.log('Tapped index', args.index)
  console.log('Tapped item', listView.items[args.index])

Emitted when a user taps an item in the ListView.

See ItemEventData.

itemsLoading ​

on('itemsLoading', (args: ItemEventData) => {
  const listView = args.object as ListView

Emitted when the ListView is loading/recycling an item. args.view is set if the ListView is recycling an item, otherwise it's undefined.

Note: frameworks use this event to update the args.view with new data.

See ItemEventData.

loadMoreItems ​

on('loadMoreItems', (args: EventData) => {
  const listView = args.object as ListView

  // example: add new items

Emitted when the user reaches the end of the ListView. Useful for loading additional items (ie. infinite scroll).

Native component ​