Listview
Using a ListView control inside Angular app requires some special attention due to the complexity of the NativeScript ListView control, with custom item templates, bindings and so on.
The NativeScript-angular plugin provides a custom Angular component which simplifies the way native ListView is used.
Note: Using the
ListView
component inside aScrollView
orScrollView
inside theListView
's items can lead to a poor user interface performance and can reflect the user experience. For avoiding those issues, we should specify the height explicitly for the ListView in the scenario when the ListView is nested inScrollView
and theScrollView
's height - when the component is used inside theListView
. Example 1 (ListView
inScrollView
):<ScrollView> <StackLayout> <ListView height="150" [items]="countries"> <ng-template let-country="item" let-i="index" let-odd="odd" let-even="even"> <!-- ....... --> </ng-template> </ListView> </StackLayout> </ScrollView>
Example 2 (
ScrollView
inListView
):<ListView [items]="countries"> <ng-template let-country="item" let-i="index" let-odd="odd" let-even="even"> <StackLayout> <ScrollView height="150" > <!-- ....... --> </ScrollView> </StackLayout> </ng-template> </ListView>
Usage
<ListView [items]="items" (itemTap)="onItemTap($event)" class="list-group">
<ng-template let-item="item" let-i="index" let-odd="odd" let-even="even">
<!-- The item template can only have a single root view container (e.g. GridLayout, StackLayout, etc.)-->
<GridLayout>
<Label [text]="item.name" class="list-group-item"></Label>
</GridLayout>
</ng-template>
</ListView>
import { Component, OnInit } from "@angular/core";
import { ItemService, Item } from "./usage.service";
import { ItemEventData } from "tns-core-modules/ui/list-view";
@Component({
moduleId: module.id,
templateUrl: "./usage.component.html"
})
export class ListViewUsageComponent implements OnInit {
items: Array<Item>;
constructor(private _itemService: ItemService) { }
ngOnInit(): void {
this.items = this._itemService.getItems();
}
onItemTap(args: ItemEventData) {
console.log(`Index: ${args.index}; View: ${args.view} ; Item: ${this.items[args.index]}`);
}
}
import { Injectable } from "@angular/core";
import { ListViewExamplesModule } from "../listview-examples.module";
@Injectable({
providedIn: "root"
})
export class ItemService {
private items = new Array<Item>(
{ id: 1, name: "Ter Stegen", role: "Goalkeeper" },
{ id: 3, name: "Piqué", role: "Defender" },
{ id: 4, name: "I. Rakitic", role: "Midfielder" },
{ id: 5, name: "Sergio", role: "Midfielder" },
{ id: 6, name: "Denis Suárez", role: "Midfielder" },
{ id: 7, name: "Arda", role: "Midfielder" },
{ id: 8, name: "A. Iniesta", role: "Midfielder" },
{ id: 9, name: "Suárez", role: "Forward" },
{ id: 10, name: "Messi", role: "Forward" },
{ id: 11, name: "Neymar", role: "Forward" },
{ id: 12, name: "Rafinha", role: "Midfielder" },
{ id: 13, name: "Cillessen", role: "Goalkeeper" },
{ id: 14, name: "Mascherano", role: "Defender" },
{ id: 17, name: "Paco Alcácer", role: "Forward" },
{ id: 18, name: "Jordi Alba", role: "Defender" },
{ id: 19, name: "Digne", role: "Defender" },
{ id: 20, name: "Sergi Roberto", role: "Midfielder" },
{ id: 21, name: "André Gomes", role: "Midfielder" },
{ id: 22, name: "Aleix Vidal", role: "Midfielder" },
{ id: 23, name: "Umtiti", role: "Defender" },
{ id: 24, name: "Mathieu", role: "Defender" },
{ id: 25, name: "Masip", role: "Goalkeeper" }
);
getItems(): Array<Item> {
return this.items;
}
getItem(id: number): Item {
return this.items.filter((item) => item.id === id)[0];
}
}
export class Item {
constructor(public id: number, public name: string, public role: string) { }
}
Styling
The ListView
supports the common CSS styling (e.g., padding
, margin
, background-color
, etc.). Additionally, you can use separatorColor
, rowHeight
and iosEstimatedRowHeight
to further customize the ListView's styles.
<!--
The @nativescript/theme provides ListView CSS classes (`list-group` & `list-group-item`) for setting recommended paddings & margins for ListView items.
These class names adds a bit of spacing and the theme’s color scheme.
-->
<ListView [items]="items" class="list-group"
backgroundColor="red" separatorColor="blue">
<ng-template let-item="item">
<GridLayout height="60">
<Label [text]="item.name" class="list-group-item" color="white"></Label>
</GridLayout>
</ng-template>
</ListView>
Tips And Tricks
Item Templates
Use itemTemplateSelector
property to create multiple item templates. The itemTemplateSelector
accepts a function that returns a value for nsTemplateKey
.
<ListView [items]="items" class="list-group" [itemTemplateSelector]="templateSelector" row="0">
<ng-template nsTemplateKey="red" let-item="item" let-i="index">
<GridLayout>
<Label [text]="item.name" backgroundColor="red" color="white"></Label>
</GridLayout>
</ng-template>
<ng-template nsTemplateKey="green" let-item="item" let-i="index">
<GridLayout>
<Label [text]="item.name" backgroundColor="green" color="yellow"></Label>
</GridLayout>
</ng-template>
</ListView>
import { Component, Input, OnChanges, SimpleChanges, OnInit } from "@angular/core";
import { ItemService, Item } from "../usage/usage.service";
import { ItemEventData } from "tns-core-modules/ui/list-view";
@Component({
moduleId: module.id,
templateUrl: "./tips-and-tricks.component.html"
})
export class ListViewTipsComponent implements OnInit {
items: Array<Item>;
constructor(private _itemService: ItemService) { }
ngOnInit(): void {
this.items = this._itemService.getItems();
}
onItemTap(args: ItemEventData) {
console.log(`Index: ${args.index}; View: ${args.view} ; Name: ${this.items[args.index].name}`);
}
templateSelector(item: Item, index: number, items: any) {
return index % 2 === 0 ? "red" : "green";
}
}
Custom Component Template
Common scenario in Angular is to reuse given component via its selector name (e.g., sdk-child-component
). The below scenario demonstrates how to pass data from the parent ListView
to its children components (which are used as template).
<ListView [items]="items" class="list-group" [itemTemplateSelector]="templateSelector" row="0">
<ng-template nsTemplateKey="red" let-item="item" let-i="index">
<GridLayout>
<Label [text]="item.name" backgroundColor="red" color="white"></Label>
</GridLayout>
</ng-template>
<ng-template nsTemplateKey="green" let-item="item" let-i="index">
<GridLayout>
<Label [text]="item.name" backgroundColor="green" color="yellow"></Label>
</GridLayout>
</ng-template>
</ListView>
import { Component, Input, OnChanges, SimpleChanges, OnInit } from "@angular/core";
import { ItemService, Item } from "../usage/usage.service";
import { ItemEventData } from "tns-core-modules/ui/list-view";
@Component({
moduleId: module.id,
templateUrl: "./tips-and-tricks.component.html"
})
export class ListViewTipsComponent implements OnInit {
items: Array<Item>;
constructor(private _itemService: ItemService) { }
ngOnInit(): void {
this.items = this._itemService.getItems();
}
onItemTap(args: ItemEventData) {
console.log(`Index: ${args.index}; View: ${args.view} ; Name: ${this.items[args.index].name}`);
}
templateSelector(item: Item, index: number, items: any) {
return index % 2 === 0 ? "red" : "green";
}
}
Properties
Name | Type | Description |
---|---|---|
items |
Array<any> | ItemsSource
|
Gets or set the items collection of the ListView . The items property can be set to an array or an object defining length and getItem(index) method. |
itemTemplateSelector |
function |
A function that returns the appropriate ket template based on the data item. |
itemTemplates |
Array<KeyedTemplate> |
Gets or set the list of item templates for the item template selector. |
separatorColor |
string | Color
|
Gets or set the items separator line color of the ListView. |
rowHeight |
Length |
Gets or set row height of the ListView. |
iosEstimatedRowHeight |
Length |
Gets or set the estimated height of rows in the ListView. Default value: 44px |
Methods
| refresh()
| Forces the ListView to reload all its items. |
| scrollToIndex(index: number)
| Scrolls the specified item with index into view. |
| scrollToIndexAnimated(index: number)
| Scrolls the specified item with index into view with animation. |
| isItemAtIndexVisible(index: number): boolean
| Checks if specified item with index is visible. |
Events
Name | Description |
---|---|
itemLoading |
Emitted when a View for the data at the specified index should be created. |
itemTap |
Emitted when a ListView item is tapped. |
loadMoreItems |
Emitted when the ListView is scrolled so that its last item is visible. |
API References
Name | Type |
---|---|
tns-core-modules/ui/list-view | Module |
ListView | Class |
ItemEventData | Interface |
ItemsSource | Interface |
KeyedTemplate | Interface |
Native Component
Android | iOS |
---|---|
android.widget.ListView | UITableView |