ListView

API Reference: UI.ListView

ListView is a View that displays given items as a one-column vertical list. Interaction with each item in the list is possible.

Return value of onRowType

  • If ListViewItem's are created from UI Editor, you shouldn't be returning 0 in onRowType method.

Callback Functions

  • Define your Listview calback functions before Page.onShow

  • You can define them in Page.onLoad

TypeScript
JavaScript
TypeScript
import PageTitleLayout from "components/PageTitleLayout";
import Color = require("sf-core/ui/color");
import ListViewDesing from 'generated/pages/listViewDesing';
import Label = require("sf-core/ui/label");
import Application = require('sf-core/application');
import addChild from "@smartface/contx/lib/smartface/action/addChild";
import FlexLayout = require('sf-core/ui/flexlayout');
import ListView = require('sf-core/ui/listview');
import ListViewItem = require('sf-core/ui/listviewitem');
import TextAlignment = require('sf-core/ui/textalignment');
import Font = require('sf-core/ui/font');
type DatasetType = { title: String, backgroundColor: Color };
const SPAN_COUNT: number = 1;
const COLORS: string[] = [
"#ffffff", "#e6f7ff", "#cceeff", "#b3e6ff", "#99ddff", "#80d4ff", "#66ccff",
"#4dc3ff", "#33bbff", "#1ab2ff", "#00aaff", "#0099e6", "#0088cc", "#0077b3",
"#006699"
];
//You should create new Page from UI-Editor and extend with it.
export default class ListViewSample extends ListViewDesing {
myListView: ListView;
index: number = 0;
myDataSet: DatasetType[] = [{
title: 'Smartface Title 1',
backgroundColor: Color.create("#99d9f9")
}, {
title: 'Smartface Title 2',
backgroundColor: Color.create("#66c6f6")
}, {
title: 'Smartface Title 3',
backgroundColor: Color.create("#32b3f3")
}, {
title: 'Smartface Title 4',
backgroundColor: Color.create("#00a1f1")
}, {
title: 'Smartface Title 5',
backgroundColor: Color.create("#00a1f1")
}, {
title: 'Smartface Title 6',
backgroundColor: Color.create("#00a1f1")
}, {
title: 'Smartface Title 7',
backgroundColor: Color.create("#00a1f1")
}, {
title: 'Smartface Title 8',
backgroundColor: Color.create("#00a1f1")
}, {
title: 'Smartface Title 9',
backgroundColor: Color.create("#00a1f1")
}];
constructor() {
super();
this.layout.flexDirection = FlexLayout.FlexDirection.ROW;
this.layout.justifyContent = FlexLayout.JustifyContent.CENTER;
this.layout.alignItems = FlexLayout.AlignItems.CENTER;
// Overrides super.onShow method
this.onShow = onShow.bind(this, this.onShow.bind(this));
// Overrides super.onLoad method
this.onLoad = onLoad.bind(this, this.onLoad.bind(this));
}
}
/**
* @event onShow
* This event is called when a page appears on the screen (everytime).
* @param {function} superOnShow super onShow function
* @param {Object} parameters passed from Router.go function
*/
function onShow(superOnShow) {
const { headerBar } = this;
superOnShow();
Application.statusBar.visible = false;
headerBar.visible = false;
}
/**
* @event onLoad
* This event is called once when page is created.
* @param {function} superOnLoad super onLoad function
*/
function onLoad(superOnLoad) {
superOnLoad();
const { myDataSet } = this;
this.headerBar.titleLayout = new PageTitleLayout();
this.myListView = new ListView({
itemCount: myDataSet.length
});
this.myListView.onRowCreate = () => {
let myListViewItem = new ListViewItem();
let myLabelTitle = new Label();
myLabelTitle.font = Font.create(Font.DEFAULT, 15, Font.BOLD);
myLabelTitle.textAlignment = TextAlignment.MIDCENTER;
myLabelTitle.textColor = Color.WHITE;
myLabelTitle.borderRadius = 10;
this.myListView.dispatch(addChild(`listViewItem${++this.index}`, myListViewItem));
//@ts-ignore
myListViewItem.addChild(myLabelTitle, `myLabelTitle${this.index}`, ".sf-listViewItem", {
marginTop: 10,
marginBottom: 10,
marginLeft: 50,
marginRight: 50,
width: null,
flexProps: {
flexGrow: 1
}
});
//@ts-ignore
myListViewItem.myLabelTitle = myLabelTitle;
return myListViewItem;
};
this.myListView.onRowBind = (listViewItem, index) => {
let myLabelTitle = listViewItem.myLabelTitle;
myLabelTitle.text = myDataSet[index].title;
myLabelTitle.backgroundColor = myDataSet[index].backgroundColor;
};
this.myListView.onRowSelected = (listViewItem, index) => {
console.log("selected index = " + index)
};
this.myListView.onPullRefresh = () => {
myDataSet.push({
title: 'Smartface Title ' + (myDataSet.length + 1),
backgroundColor: Color.RED,
})
this.myListView.itemCount = myDataSet.length;
this.myListView.refreshData();
this.myListView.stopRefresh();
}
this.layout.addChild(this.myListView, 'myListView', ".sf-listView", (userProps) => {
userProps.height = 350;
userProps.rowHeight = 70;
return userProps;
});
this.dispatch({
type: "updateUserStyle",
userStyle: {
paddingTop: 0,
paddingLeft: 0,
paddingBottom: 0,
paddingRight: 0,
}
});
}
JavaScript
const Page = require("sf-core/ui/page");
const extend = require("js-base/core/extend");
const Color = require('sf-core/ui/color');
const Label = require('sf-core/ui/label');
const FlexLayout = require('sf-core/ui/flexlayout');
const ListView = require('sf-core/ui/listview');
const ListViewItem = require('sf-core/ui/listviewitem');
const TextAlignment = require('sf-core/ui/textalignment');
const Font = require('sf-core/ui/font');
var Page1 = extend(Page)(
function(_super) {
_super(this, {
onShow: function(params) {
Application.statusBar.visible = false;
this.headerBar.visible = false;
}
});
this.layout.flexDirection = FlexLayout.FlexDirection.ROW;
this.layout.justifyContent = FlexLayout.JustifyContent.CENTER;
this.layout.alignItems = FlexLayout.AlignItems.CENTER;
var myDataSet = [{
title: 'Smartface Title 1',
backgroundColor: Color.create("#99d9f9")
}, {
title: 'Smartface Title 2',
backgroundColor: Color.create("#66c6f6")
}, {
title: 'Smartface Title 3',
backgroundColor: Color.create("#32b3f3")
}, {
title: 'Smartface Title 4',
backgroundColor:Color.create("#00a1f1")
}, {
title: 'Smartface Title 5',
backgroundColor:Color.create("#00a1f1")
}, {
title: 'Smartface Title 6',
backgroundColor:Color.create("#00a1f1")
}, {
title: 'Smartface Title 7',
backgroundColor:Color.create("#00a1f1")
}, {
title: 'Smartface Title 8',
backgroundColor:Color.create("#00a1f1")
}, {
title: 'Smartface Title 9',
backgroundColor:Color.create("#00a1f1")
}];
var myListView = new ListView({
height:350,
rowHeight: 70,
itemCount: myDataSet.length,
});
this.layout.addChild(myListView);
myListView.onRowCreate = function() {
var myListViewItem = new ListViewItem();
var myLabelTitle = new Label({
flexGrow:1,
marginTop: 10,
marginBottom: 10,
marginLeft: 50,
marginRight: 50
});
myLabelTitle.font = Font.create(Font.DEFAULT, 15, Font.BOLD);
myLabelTitle.textAlignment = TextAlignment.MIDCENTER;
myLabelTitle.textColor = Color.WHITE;
myLabelTitle.borderRadius = 10;
myListViewItem.addChild(myLabelTitle);
myListViewItem.myLabelTitle = myLabelTitle;
return myListViewItem;
};
myListView.onRowBind = function(listViewItem, index) {
var myLabelTitle = listViewItem.myLabelTitle;
myLabelTitle.text = myDataSet[index].title;
myLabelTitle.backgroundColor = myDataSet[index].backgroundColor;
};
myListView.onRowSelected = function(listViewItem, index) {
console.log("selected index = " + index)
};
myListView.onPullRefresh = function() {
myDataSet.push({
title: 'Smartface Title ' + (myDataSet.length+1),
backgroundColor: Color.RED,
})
myListView.itemCount = myDataSet.length;
myListView.refreshData();
myListView.stopRefresh();
}
}
);
module.exports = Page1;

Using Multiple ListViewItem's

TypeScript
JavaScript
TypeScript
import PageTitleLayout from "components/PageTitleLayout";
import Color = require("sf-core/ui/color");
import ListViewDesing from 'generated/pages/listViewDesing';
import Label = require("sf-core/ui/label");
import Application = require('sf-core/application');
import addChild from "@smartface/contx/lib/smartface/action/addChild";
import FlexLayout = require('sf-core/ui/flexlayout');
import ListView = require('sf-core/ui/listview');
import ListViewItem = require('sf-core/ui/listviewitem');
import Font = require('sf-core/ui/font');
type RowDataType = Array<Array<String>>;
type DataType = { isHeader: boolean, data: String };
//You should create new Page from UI-Editor and extend with it.
export default class ListViewSample extends ListViewDesing {
myListView: ListView;
index: number = 0;
headerData: string[] = [
"Complementary",
"Analogous",
"Tetradic",
"Monochromatic"
];
rowData: Array<Array<String>> = [
["#ffb8c9", "#b8ffee"],
["#ffb8ed", "#ffb8c9", "#ffcbb8"],
["#eeb8ff", "#ffb8c9", "#c9ffb8", "#b8ffee"],
["#ff6c8f", "#ff85a2", "#ff9fb6", "#ffb8c9", "#ffd2dc", "#ffebf0"]
];
dataArray: DataType[] = this.pushDataToArray(this.headerData, this.rowData);
constructor() {
super();
this.layout.flexDirection = FlexLayout.FlexDirection.ROW;
this.layout.justifyContent = FlexLayout.JustifyContent.CENTER;
this.layout.alignItems = FlexLayout.AlignItems.CENTER;
// Overrides super.onShow method
this.onShow = onShow.bind(this, this.onShow.bind(this));
// Overrides super.onLoad method
this.onLoad = onLoad.bind(this, this.onLoad.bind(this));
}
pushDataToArray(headerData: string[], rowData: RowDataType): DataType[] {
let dataArray: DataType[] = new Array<DataType>()
for (var i = 0; i < headerData.length; i++) {
dataArray.push({ isHeader: true, data: headerData[i] });
for (var j = 0; j < rowData[i].length; j++) {
dataArray.push({ isHeader: false, data: rowData[i][j] });
}
}
return dataArray;
};
}
/**
* @event onShow
* This event is called when a page appears on the screen (everytime).
* @param {function} superOnShow super onShow function
* @param {Object} parameters passed from Router.go function
*/
function onShow(superOnShow) {
const { headerBar } = this;
superOnShow();
Application.statusBar.visible = false;
headerBar.visible = false;
}
/**
* @event onLoad
* This event is called once when page is created.
* @param {function} superOnLoad super onLoad function
*/
function onLoad(superOnLoad) {
superOnLoad();
const { dataArray } = this;
this.headerBar.titleLayout = new PageTitleLayout();
this.myListView = new ListView({
itemCount: dataArray.length
});
this.myListView.onRowCreate = (type) => {
let myListViewItem = new ListViewItem();
this.myListView.dispatch(addChild(`myListViewItem${++this.index}`, myListViewItem));
if (type == 1) {
let myLabelTitle = new Label();
//@ts-ignore
myListViewItem.addChild(myLabelTitle, `myLabelTitle${this.index}`, ".sf-label", {
flexProps: {
flexGrow: 1
},
textAlignment: "MIDCENTER",
borderRadius: 10,
margin: 10
});
//@ts-ignore
myListViewItem.myLabelTitle = myLabelTitle;
} else { // Header
let myLabelTitle = new Label();
myLabelTitle.font = Font.create(Font.DEFAULT, 30, Font.BOLD);
myLabelTitle.backgroundColor = Color.WHITE;
//@ts-ignore
myListViewItem.addChild(myLabelTitle, `myLabelTitle${this.index}`, ".sf-label", {
flexProps: {
flexGrow: 1
},
borderRadius: 10,
margin: 10,
font: {
size: 30,
bold: true,
family: "SFProText",
style: "Semibold"
}
});
//@ts-ignore
myListViewItem.myLabelTitle = myLabelTitle;
}
return myListViewItem;
};
this.myListView.onRowHeight = function (index) {
if (dataArray[index].isHeader) {
return 100;
}
return 70;
};
this.myListView.onRowBind = function (listViewItem, index) {
const { myLabelTitle } = listViewItem;
if (dataArray[index].isHeader) {
myLabelTitle.text = dataArray[index].data;
} else {
myLabelTitle.backgroundColor = Color.create(dataArray[index].data);
myLabelTitle.text = dataArray[index].data;
}
};
this.myListView.onRowType = function (index) {
if (dataArray[index].isHeader) {
return 2;
} else {
return 1;
}
};
this.myListView.onPullRefresh = () => {
let header = ["Triadic"];
let row = [["#b8c9ff", "#ffb8c9", "#c9ffb8"]];
this.pushDataToArray(header, row);
this.myListView.itemCount = dataArray.length;
this.myListView.refreshData();
this.myListView.stopRefresh();
}
this.layout.addChild(this.myListView, 'myListView', ".sf-listView", (userProps) => {
userProps.width = null;
userProps.height = null;
userProps.flexGrow = 1;
userProps.marginLeft = 20;
userProps.marginRight = 20;
userProps.marginTop = 50;
userProps.marginBottom = 50;
return userProps;
});
this.dispatch({
type: "updateUserStyle",
userStyle: {
paddingTop: 0,
paddingLeft: 0,
paddingBottom: 0,
paddingRight: 0,
}
});
}
JavaScript
const Page = require("sf-core/ui/page");
const extend = require("js-base/core/extend");
const Color = require('sf-core/ui/color');
const Label = require('sf-core/ui/label');
const FlexLayout = require('sf-core/ui/flexlayout');
const ListView = require('sf-core/ui/listview');
const ListViewItem = require('sf-core/ui/listviewitem');
const Font = require('sf-core/ui/font');
const TextAlignment = require('sf-core/ui/textalignment');
var Page1 = extend(Page)(
function(_super) {
_super(this, {
onShow: function(params) {
Application.statusBar.visible = false;
this.headerBar.visible = false;
}
});
var _headerData = [
"Complementary",
"Analogous",
"Tetradic",
"Monochromatic"
];
var _rowData = [
["#ffb8c9","#b8ffee"],
["#ffb8ed","#ffb8c9","#ffcbb8"],
["#eeb8ff","#ffb8c9","#c9ffb8","#b8ffee"],
["#ff6c8f","#ff85a2","#ff9fb6","#ffb8c9","#ffd2dc","#ffebf0"]
];
var dataArray = [];
function pushDataToArray(headerData,rowData){
for (var i = 0; i < headerData.length; i++) {
dataArray.push({isHeader : true, data : headerData[i]});
for (var j = 0; j < rowData[i].length; j++) {
dataArray.push({isHeader : false, data : rowData[i][j]});
}
}
};
pushDataToArray(_headerData,_rowData);
var myListView = new ListView({
flexGrow: 1,
marginLeft: 20,
marginRight: 20,
marginTop: 50,
marginBottom: 50,
itemCount: dataArray.length,
});
this.layout.addChild(myListView);
myListView.onRowCreate = function(type) {
var myListViewItem = new ListViewItem();
if (type == 1) {
var myLabelTitle = new Label({
flexGrow: 1,
margin: 10
});
myLabelTitle.textColor = Color.WHITE;
myLabelTitle.borderRadius = 10;
myLabelTitle.textAlignment = TextAlignment.MIDCENTER;
myListViewItem.addChild(myLabelTitle);
myListViewItem.myLabelTitle = myLabelTitle;
}else{ // Header
var myLabelTitle = new Label({
flexGrow: 1,
margin: 10
});
myLabelTitle.font = Font.create(Font.DEFAULT, 30, Font.BOLD);
myLabelTitle.backgroundColor = Color.WHITE;
myListViewItem.addChild(myLabelTitle);
myListViewItem.myLabelTitle = myLabelTitle;
}
return myListViewItem;
};
myListView.onRowHeight = function(index){
if (dataArray[index].isHeader) {
return 100;
}
return 70;
};
myListView.onRowBind = function(listViewItem, index) {
var myLabelTitle = listViewItem.myLabelTitle;
if (dataArray[index].isHeader) {
myLabelTitle.text = dataArray[index].data;
}else{
myLabelTitle.backgroundColor = Color.create(dataArray[index].data);
myLabelTitle.text = dataArray[index].data;
}
};
myListView.onRowType = function(index){
if (dataArray[index].isHeader) {
return 2;
}else{
return 1;
}
};
myListView.onPullRefresh = function() {
var header = ["Triadic"];
var row = [["#b8c9ff","#ffb8c9","#c9ffb8"]];
pushDataToArray(header,row);
myListView.itemCount = dataArray.length;
myListView.refreshData();
myListView.stopRefresh();
}
}
);
module.exports = Page1;

Lazy Loading (Pagination)

Lazy loading of ListView is easy on Smartface Native Framework. It is possible with:

  • onScroll event

  • onRowBind event

Please note that onScroll event will be fired while user scrolling the ListView. This means while you downloading your content for lazy loading, onScroll event will continue to firing. You should check that. We recommend to use onRowBind for lazy loading to get over from this problem.

Lazy Loading Using onRowBind (recommended)

TypeScript
JavaScript
TypeScript
import PageTitleLayout from "components/PageTitleLayout";
import Color = require("sf-core/ui/color");
import Page2Design from 'generated/pages/page2';
import Label = require("sf-core/ui/label");
import Application = require('sf-core/application');
import addChild from "@smartface/contx/lib/smartface/action/addChild";
import FlexLayout = require('sf-core/ui/flexlayout');
import ListView = require('sf-core/ui/listview');
import ListViewItem = require('sf-core/ui/listviewitem');
import ActivityIndicator = require("sf-core/ui/activityindicator");
import Timer = require("sf-core/timer");
import TextAlignment = require("sf-core/ui/textalignment");
type DatasetType = { title: String, subtitle?: String, backgroundColor?: Color };
const COLORS: string[] = [
"#ffffff", "#e6f7ff", "#cceeff", "#b3e6ff", "#99ddff", "#80d4ff", "#66ccff",
"#4dc3ff", "#33bbff", "#1ab2ff", "#00aaff", "#0099e6", "#0088cc", "#0077b3",
"#006699"
];
//You should create new Page from UI-Editor and extend with it.
export default class ListViewSample extends Page2Design {
myListView: ListView;
index: number = 0;
isLoading: boolean = false;
myDataSet: DatasetType[] = [{
title: 'Smartface Title 1',
subtitle: 'Smartface Subtitle 1',
}, {
title: 'Smartface Title 2',
subtitle: 'Smartface Subtitle 2',
}, {
title: 'Smartface Title 3',
subtitle: 'Smartface Subtitle 3',
}, {
title: 'Smartface Title 4',
subtitle: 'Smartface Subtitle 4',
}, {
title: 'Smartface Title 5',
subtitle: 'Smartface Subtitle 5',
}, {
title: 'Smartface Title 6',
subtitle: 'Smartface Subtitle 6',
}, {
title: 'Smartface Title 7',
subtitle: 'Smartface Subtitle 7',
}];
constructor() {
super();
this.layout.flexDirection = FlexLayout.FlexDirection.ROW;
this.layout.justifyContent = FlexLayout.JustifyContent.CENTER;
this.layout.alignItems = FlexLayout.AlignItems.CENTER;
// Overrides super.onShow method
this.onShow = onShow.bind(this, this.onShow.bind(this));
// Overrides super.onLoad method
this.onLoad = onLoad.bind(this, this.onLoad.bind(this));
}
pushMoreToDataset(count: number): void {
for (let i = 0; i < count; i++) {
this.myDataSet.push({
title: 'Smartface Title ' + (this.myDataSet.length + 1),
subtitle: 'Smartface Subitle ' + (this.myDataSet.length + 1),
});
}
}
}
/**
* @event onShow
* This event is called when a page appears on the screen (everytime).
* @param {function} superOnShow super onShow function
* @param {Object} parameters passed from Router.go function
*/
function onShow(superOnShow) {
const { headerBar } = this;
superOnShow();
Application.statusBar.visible = false;
headerBar.visible = false;
}
/**
* @event onLoad
* This event is called once when page is created.
* @param {function} superOnLoad super onLoad function
*/
function onLoad(superOnLoad) {
superOnLoad();
let { myDataSet, isLoading } = this;
this.headerBar.titleLayout = new PageTitleLayout();
this.myListView = new ListView({
itemCount: myDataSet.length + 1,
onRowCreate: (type) => {
let myListViewItem = new ListViewItem();
this.myListView.dispatch(addChild(`myListViewItem${++this.index}`, myListViewItem, '.sf-listViewItem', {
paddingTop: 5,
paddingBottom: 5
}));
if (type == 2) {// Loading
let loadingIndicator = new ActivityIndicator();
//@ts-ignore
myListViewItem.loadingIndicator = loadingIndicator;
//@ts-ignore
myListViewItem.addChild(loadingIndicator, `loadingIndicator${this.index}`, ".sf-activityIndicator", {
width: 35,
height: 35,
color: "#008000",
flexProps: {
positionType: "ABSOLUTE",
}
});
//@ts-ignore
myListViewItem.dispatch({
type: "updateUserStyle",
userStyle: {
flexProps: {
justifyContent: "CENTER",
alignItems: "CENTER"
}
}
});
} else {
let titleLayout = new FlexLayout();
let titleLabel = new Label();
let subtitleLabel = new Label();
//@ts-ignore
myListViewItem.addChild(titleLayout, `titleLayout${this.index}`, ".sf-flexLayout", {
flexGrow: 1,
backgroundColor: "#00A1F1"
});
//@ts-ignore
titleLayout.addChild(titleLabel, `titleLabel${this.index}`, "sf-label", {
textAlignment: "MIDCENTER",
flexGrow: 1,
textColor: "#FFFFFF"
});
//@ts-ignore
titleLayout.titleLabel = titleLabel;
//@ts-ignore
titleLayout.addChild(subtitleLabel, `subtitleLabel${this.index}`, "sf-label", {
textAlignment: "MIDCENTER",
flexGrow: 1,
textColor: "#FFFFFF"
});
//@ts-ignore
titleLayout.subtitleLabel = subtitleLabel;
//@ts-ignore
myListViewItem.titleLayout = titleLayout;
}
return myListViewItem;
},
onRowBind: (listViewItem, index) => {
if (index === myDataSet.length) {
listViewItem.loadingIndicator.visible = true;
}
else {
listViewItem.titleLayout.titleLabel.text = myDataSet[index % myDataSet.length].title;
listViewItem.titleLayout.subtitleLabel.text = myDataSet[index % myDataSet.length].subtitle;
}
if (index > myDataSet.length - 3 && !isLoading) {
isLoading = true;
Timer.setTimeout({
task: () => {
// Loading completed
this.pushMoreToDataset(10);
this.myListView.itemCount = myDataSet.length + 1;
this.myListView.refreshData();
isLoading = false;
},
delay: 1500
});
}
},
onPullRefresh: () => {
this.pushMoreToDataset(1);
this.myListView.itemCount = myDataSet.length + 1;
this.myListView.refreshData();
this.myListView.stopRefresh();
},
onRowType: (index) => {
if (myDataSet.length === index) {// Loading
return 2;
} else {
return 1;
}
}
});
this.layout.addChild(this.myListView, 'myListView', ".sf-listView", (userProps: any) => {
userProps.rowHeight = 100;
userProps.alignSelf = "CENTER";
userProps.width = null;
userProps.height = null;
userProps.flexGrow = 1;
userProps.marginLeft = 75;
userProps.marginRight = 75;
userProps.marginTop = 100;
userProps.marginBottom = 100;
return userProps;
});
this.dispatch({
type: "updateUserStyle",
userStyle: {
paddingTop: 0,
paddingLeft: 0,
paddingBottom: 0,
paddingRight: 0,
flexProps: {
justifyContent: "CENTER"
}
}
});
}
JavaScript
const extend = require("js-base/core/extend");
const Page = require("sf-core/ui/page");
const Timer = require("sf-core/timer");
const Label = require("sf-core/ui/label");
const Color = require("sf-core/ui/color");
const ListView = require("sf-core/ui/listview");
const FlexLayout = require("sf-core/ui/flexlayout");
const ListViewItem = require("sf-core/ui/listviewitem");
const TextAlignment = require("sf-core/ui/textalignment");
const ActivityIndicator = require("sf-core/ui/activityindicator");
var myDataSet = [{
title: 'Smartface Title 1',
subtitle: 'Smartface Subtitle 1',
}, {
title: 'Smartface Title 2',
subtitle: 'Smartface Subtitle 2',
}, {
title: 'Smartface Title 3',
subtitle: 'Smartface Subtitle 3',
}, {
title: 'Smartface Title 4',
subtitle: 'Smartface Subtitle 4',
}, {
title: 'Smartface Title 5',
subtitle: 'Smartface Subtitle 5',
}, {
title: 'Smartface Title 6',
subtitle: 'Smartface Subtitle 6',
}, {
title: 'Smartface Title 7',
subtitle: 'Smartface Subtitle 7',
}];
var isLoading = false;
var Page1 = extend(Page)(
function(_super) {
_super(this);
var myListView = new ListView({
flexGrow: 1,
marginLeft: 75,
marginRight: 75,
marginTop: 100,
marginBottom: 100,
rowHeight: 100,
alignSelf: FlexLayout.AlignSelf.CENTER,
itemCount: myDataSet.length + 1,
onRowCreate: function(type) {
var myListViewItem = new ListViewItem({
paddingTop: 5,
paddingBottom: 5
});
if (type == 2) {// Loading
var loadingIndicator = new ActivityIndicator({
color: Color.GREEN,
width:20,
height:20,
positionType: FlexLayout.PositionType.ABSOLUTE,
});
myListViewItem.justifyContent = FlexLayout.JustifyContent.CENTER;
myListViewItem.alignItems = FlexLayout.AlignItems.CENTER;
myListViewItem.loadingIndicator = loadingIndicator;
myListViewItem.addChild(loadingIndicator);
}else{
var titleLayout = new FlexLayout({
flexGrow: 2,
backgroundColor: Color.create("#00A1F1"),
});
var titleLabel = new Label({
flexGrow: 1,
textColor: Color.WHITE,
textAlignment: TextAlignment.MIDCENTER,
});
var subtitleLabel = new Label({
flexGrow: 1,
textColor: Color.WHITE,
textAlignment: TextAlignment.MIDCENTER,
});
titleLayout.addChild(titleLabel);
titleLayout.titleLabel = titleLabel;
titleLayout.addChild(subtitleLabel);
titleLayout.subtitleLabel = subtitleLabel;
myListViewItem.addChild(titleLayout);
myListViewItem.titleLayout = titleLayout;
}
return myListViewItem;
},
onRowBind: function(listViewItem, index) {
// means loading
if (index === myDataSet.length) {
listViewItem.loadingIndicator.visible = true;
}
else {
listViewItem.titleLayout.titleLabel.text = myDataSet[index % myDataSet.length].title;
listViewItem.titleLayout.subtitleLabel.text = myDataSet[index % myDataSet.length].subtitle;
}
if(index > myDataSet.length - 3 && !isLoading){
isLoading = true;
Timer.setTimeout({
task: function() {
// Loading completed
pushMoreToDataset(myDataSet, 10);
myListView.itemCount = myDataSet.length + 1;
myListView.refreshData();
isLoading = false;
},
delay: 1500
});
}
},
onPullRefresh: function() {
pushMoreToDataset(myDataSet, 1);
myListView.itemCount = myDataSet.length + 1;
myListView.refreshData();
myListView.stopRefresh();
},
onRowType: function(index){
if (myDataSet.length === index) {// Loading
return 2;
}else{
return 1;
}
}
});
this.layout.justifyContent = FlexLayout.JustifyContent.CENTER;
this.layout.addChild(myListView);
}
);
// Generating random dataset element
function pushMoreToDataset(myDataSet, count) {
for (var i = 0; i < count; i++) {
myDataSet.push({
title: 'Smartface Title ' + (myDataSet.length + 1),
subtitle: 'Smartface Subitle ' + (myDataSet.length + 1),
});
}
}
module.exports = Page1;

Lazy Loading Using onScroll

TypeScript
JavaScript
TypeScript
import PageTitleLayout from "components/PageTitleLayout";
import Color = require("sf-core/ui/color");
import Page2Design from 'generated/pages/page2';
import Label = require("sf-core/ui/label");
import Application = require('sf-core/application');
import addChild from "@smartface/contx/lib/smartface/action/addChild";
import FlexLayout = require('sf-core/ui/flexlayout');
import ListView = require('sf-core/ui/listview');
import ListViewItem = require('sf-core/ui/listviewitem');
import ActivityIndicator = require("sf-core/ui/activityindicator");
import Timer = require("sf-core/timer");
import TextAlignment = require("sf-core/ui/textalignment");
type DatasetType = { title: String, subtitle?: String, backgroundColor?: Color };
const COLORS: string[] = [
"#ffffff", "#e6f7ff", "#cceeff", "#b3e6ff",