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 from "sf-core/ui/color";
import ListViewDesign from 'generated/pages/listViewDesign';
import Label from "sf-core/ui/label";
import Application from 'sf-core/application';
import addChild from "@smartface/contx/lib/smartface/action/addChild";
import FlexLayout from 'sf-core/ui/flexlayout';
import ListView from 'sf-core/ui/listview';
import ListViewItem from 'sf-core/ui/listviewitem';
import TextAlignment from 'sf-core/ui/textalignment';
import Font from '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 ListViewDesign {
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 from "sf-core/ui/color";
import ListViewDesign from 'generated/pages/listViewDesign';
import Label from "sf-core/ui/label";
import Application from 'sf-core/application';
import addChild from "@smartface/contx/lib/smartface/action/addChild";
import FlexLayout from 'sf-core/ui/flexlayout';
import ListView from 'sf-core/ui/listview';
import ListViewItem from 'sf-core/ui/listviewitem';
import Font from 'sf-core/ui/font';
type RowDataType = string[][];
type DataType = { isHeader: boolean, data: String };
//You should create new Page from UI-Editor and extend with it.
export default class ListViewSample extends ListViewDesign {
myListView: ListView;
index: number = 0;
headerData: string[] = [
"Complementary",
"Analogous",
"Tetradic",
"Monochromatic"
];
rowData: 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;

scrollTo method

API Reference: scrollTo

When using scrollTo method, you should check if listview has enough data in it.

this.data = [ { text: "Smartface } ];
/**
* This may cause unexpected behavior since the listView doesn't have
enough length to scroll to.
*/
this.listView1.scrollTo(3);
// You should do it like this
if (this.data.length > 3 ) {
this.listView1.scrollTo(3);
}

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 from "sf-core/ui/color";
import Page2Design from 'generated/pages/page2';
import Label from "sf-core/ui/label";
import Application from 'sf-core/application';
import addChild from "@smartface/contx/lib/smartface/action/addChild";
import FlexLayout from 'sf-core/ui/flexlayout';
import ListView from 'sf-core/ui/listview';
import ListViewItem from 'sf-core/ui/listviewitem';
import ActivityIndicator from "sf-core/ui/activityindicator";
import Timer from "sf-core/global/timer";
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 from "sf-core/ui/color";
import Page2Design from 'generated/pages/page2';
import Label from "sf-core/ui/label";
import Application from 'sf-core/application';
import addChild from "@smartface/contx/lib/smartface/action/addChild";
import FlexLayout from 'sf-core/ui/flexlayout';
import ListView from 'sf-core/ui/listview';
import ListViewItem from 'sf-core/ui/listviewitem';
import ActivityIndicator from "sf-core/ui/activityindicator";
import Timer from "sf-core/timer";
import TextAlignment from "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"
];