- ListView basics
- ListItem templates
- Handling events
class lets you create high-performance, vertically scrolling lists. To achieve the fast-scrolling behavior expected in mobile applications, the
ListView class manages the life cycle (creation, deletion, updating) of individual list items itself, rather than the application developer. Instead, the developer provides one or more list item templates that define an item's presentation, and a list of data items for the list to display. As the user scrolls through the list, the data items are cycled through a limited number of rendered list view items.
In Alloy, a ListView consists minimally of a
ListView/> element that contains one or more
<ListSection/> elements, which in turn contain one or more of <
ListItem/ > elements. You can declaratively populate a ListView (using the default list item template), as shown below.
Assigning data programmatically to a ListView
For small data sets, it's convenient to declaratively create the ListItems in the XML view, as shown previously. For large data sets, you will likely want to separate the data set from its presentation. To do this, you pass an array of ListDataItem objects to the
setItems() method of a
The view controller (index.js) defines an array of
ListDataItem objects, and then calls the
setItems() method on the
ListSection to populate it.
In this case, the XML view (index.xml) can be reduced to a
<ListSection/> elements, without any
If the source data is provided in a form that doesn't match the
ListDataItem structure (for example from a web service), you can easily map it to the correct format using the included Underscore library's
map() method, as shown below.
setItems() method clears the
ListSection before setting its items. To discretely update list items, you can use the
methods of the
ListItem element has an associated template that determines how the data for that row is displayed. A template consists of standard UI elements – Label, ImageView, Button, and so forth – that are bound to specific fields in the list item data set. You can use the provided default list item template (as in the previous) examples, or create a custom template that you can apply to all list items, or apply to individual list items. On iOS, you can also use one of the additional built-in templates.
Default list item template
By default, a
ListView uses the default list item template, which consists of an image view, a black, left-aligned title label, and an optional accessory icon. On Android, the image appears on the right side of the cell, and on iOS the image appears on the left side of the cell. This is the template used in the previous examples. For example, the following XML and TSS code adds an image and a disclosure icon accessory type to each list item.
The template label's text and image source are bound to each
image attributes. If an attribute is not set on the element, then that template element is not displayed. As with any Alloy element, you can specify an attribute value in a TSS file. The following associated TSS specifies the
accessoryType for each
Custom ListItem templates
If the default
ListItem template doesn't suit your needs, you can create a custom template that defines each list item's structure and style. A custom template is a container for Titanium UI elements, such as
View. To bind list item data to a particular view element, you must assign a
bindId attribute to the element. The following illustrates the structure of a custom item template containing several (bindable) Label elements and a couple of (non-bindable) View elements.
To declare a custom item template add a
<Templates/> element to the
<ListView/> element and then add one or more named
<ItemTemplate> elements to the
<Templates/> element. A
<Templates/> element can contain multiple <ItemTemplate/> elements, each of which must have a
name attribute that uniquely identifies it.
<ItemTemplate/> add any UI elements you want to appear in each list item. To enable data binding on a given view, assign a
bindId attribute to the element. To apply the the custom template by default to all list items (rather than the built-in default item template) set the
defaultItemTemplate attribute to the value of the
name attribute you assigned to the
<ItemTemplate/>. If you have more than one custom template, you can override the default item template for a given list item by setting it's
template property. See Below for more information.
As you can see above, to declaratively bind data to the proper view element in a custom template, you specify the element's bindId and the property name to update, separated by colon. For instance,
mass:text="1.00794" means to assign the specified value to the
text property of the
<Label/> element whose
Below is the TSS file used to style the elements in the custom template.
The images below show the custom item template on iOS and Android.
Assigning data programmatically with custom templates
To programmatically bind data to view in a custom template, the object you pass to
setItems() defines custom key-value pairs. The key for each pair must match the
bindId of the child view, and its values are a dictionary of properties to bind the view. Using the
elementTemplate from the previous example, the following code assigns data to the list view:
Assigning ListItem templates
As shown in previous examples, you can assign a custom template to all list items by setting the ListView's
defaultItemTemplate. You can also assign a custom template to an individual list item's
template property. For example, the following ListView defines two custom item templates named "image_title" and "image_only". The first template consists of a
<View/> with a horizontal layout containing an
<ImageView/> and a
<Label/> element; the second uses the default (absolute) layout and contains only a
<Label/> element. These layouts are illustrated below.
The following XML view defines the two templates.
The following controller code programmatically assigns a template to each list item by setting its
If the data set you want to display in a ListView is extremely large (or perhaps infinite), it's often preferable to load an initial set of list data items. Then as the user scrolls to the end of available data, additional data items are loaded. For performance reasons, ListView doesn't support scroll events but does provide a feature called "markers". A marker identifies a point in a rendered ListView that acts like a tripwire: the first time a user scrolls past a list item where a marker has been set, it emits a marker event. Your application can respond to this event by loading additional data and set a new marker, if necessary.
The following code demonstrates how this works. In your XML view, add an
onMarker attribute to the ListView that specifies the function to handle the
setMarker(), passing it the list view section index and item index where you want to set a marker. For example, the following sets a marker at the 100th list item in the first section in the ListView.
The application loads the initial data set and sets the first marker. For the purposes of demonstration, this example use a
for() loop to generate an "infinite" data source based on the value of a state variable. In practice, your application will likely consume data from a remote or local paginated data source.
When the marker event is fired, a new set of data is generated and appended to the list view. Finally, a new marker point is set.
Handling events on ListItems
To handle click events on list items, you attach an
onItemclick attribute to the
<ListView/> that specifies the event function handler to invoke. The event handler is passed an
itemclick event whose properties identify the clicked list item (by section and item index), as well as the
bindId of of the control that generated the event, if any. For example:
itemclick handler updates the
title property of the list item and sets its
color to red, before updating the item in the list.
Handling events on template views
When using a custom template, you can also handle events on individual template view objects. For example, each list item might contain an image the user can click to indicate they like that item.
To do this, you attach an
attribute to the view element in the
<ItemTemplate/> element, whose value is the event handler to invoke when the user clicks that view object. For example, the following defines the custom template used in the above screenshot, consisting of a
<Label/> element and an
<ImageView/> element. The
<ListView/> has an
onItemclick attribute set to
"handleItemClick" to set the star image by bubbling the event down to the image view. The project's /assets folder contains two PNGs:
star_gold.png. Initially, each list item displays the grey star.
handleItemClick() event handler function, shown below, toggles the image displayed by the image between the grey and gold versions.