Using ListView with UI Editor

Overview

This guide is applicable for using UI editor on both ListView and GridView. It is advised to check them for more detailed guide.

Designing ListViewItem

  • Go to the toolbox, drag&drop a ListViewItem and perform your design inside that component. For more information please refer to our library guide.

  • Ensure that Show In Toolbox is set to true

Using ListViewItem

  • Go to Page Design from Explorer

  • From the BUILT-IN COMPONENTS drag&drop the ListView inside your page

  • Double click the ListView component to drag other components inside

  • From the toolbox menu go to the "My Components" section

  • Insert your newly created UI.ListViewItem by Drag & Drop.

Using more than one ListViewItem type

On UI Editor, Smartface Cloud IDE only supports using one UI.ListViewItem type by Drag & Drop.

After Dragging & Dropping your UI.ListViewItem, adjust rowHeight and itemCount to your needs.

Adapting ListView to ListViewItem

Setting itemCount

itemCount determines how many items is going to be shown on UI.ListView, therefore this property needs to be changed when related dataset changes.

contentInset and contentOffset

Since padding will not work on UI.ListViewItem, you might want to leave extra space only on the latest or the first item. You can use contentInset or contentOffset on such cases. Using UI editor with class is recommended by Smartface, to keep the code clean.

Important

When defining contentInset and contentOffset , make sure that you define both bottom and top, even if you are not using one of them. Only defining one of them might cause unexpected behaviors.

Coding ListViewItem

  • When a component is created on library pane by using Reusable Component Libraries a file that contains component code like scripts/components/ListViewItem1.ts is created.

  • While using your newly added layouts ( e.g. changing text ), it is crucial to encapsulate inner layouts and define them as properties by using getter and setters. This will help page code to be clean, improve extendibility and maximize reusability.

scripts/components/ListViewItem1.ts
scripts/components/ListViewItem1.ts
import ListViewItem1Design from 'generated/my-components/ListViewItem1';
export default class ListViewItem1 extends ListViewItem1Design {
pageName?: string | undefined;
private __titleText = ''; // Alternative method to assign variable
constructor(props?: any, pageName?: string) {
// Initalizes super class for this scope
super(props);
this.pageName = pageName;
}
get titleText(): string {
return this.label1.text || '';
//return this.__titleText;
}
set titleText(value: string) {
this.label1.text = typeof value === 'string' ? value : '';
// E.g. you can check its type to avoid wrong assignments
this.__titleText = typeof value === 'string' ? value : '';
}
}

Adding layouts inside of ListViewItem

If the layout needs to be reached from the code, ensure that the layouts have their Assign to Page variable is set to true

Using ListViewItem on Page with ListView

After the properties and codes are created, it is time to use it on Actual page.

When UI.ListViewItem is added by UI Editor, using onRowCreate callback is not necessary, this will help to keep the code clean.

UI.ListView needs to be initialized, then the data should be defined properly.

By default, Smartface sets rowHeight and itemCount value to something reasonable. To change that, simply set those values inside of initListView() function.

ListView with multiple types

To use more than one Type, use onRowCreate function and add your types from the code. Refer the ListView Guide for details.

scripts/pages/page1.ts
scripts/components/ListViewItem1.ts
../components/ListViewItem1.json
scripts/pages/page1.ts
import ListViewItem1 from "components/ListViewItem1";
export default class Page1 extends Page1Design {
router: any;
constructor () {
super();
this.onShow = onShow.bind(this, this.onShow.bind(this));
this.onLoad = onLoad.bind(this, this.onLoad.bind(this));
}
initListView() {
this.listView1.rowHeight = ListViewItem1.getHeight();
this.listView1.onRowBind = (listViewItem: ListViewItem1, index: number) => {
listViewItem.titleText = this.dataSet[index].title; // Recommended way
};
this.listView1.onPullRefresh = async () => {
try {
await apiCall();
this.refreshListView();
}
finally {
this.listView1.stopRefresh();
}
}
}
refreshListView() {
this.listView1.itemCount = this.dataSet.length;
this.listView1.refreshData();
}
}
function onShow(superOnShow: () => void) {
superOnShow();
this.refreshListView();
}
function onLoad(superOnLoad: () => void) {
superOnLoad();
this.dataSet = [{
title: "Smartface1"
},{
title: "Smartface2"
}]
this.initListView();
}
scripts/components/ListViewItem1.ts
import ListViewItem1Design from 'generated/my-components/ListViewItem1';
import { getCombinedStyle } from 'sf-extension-utils/lib/getCombinedStyle';
export default class ListViewItem1 extends ListViewItem1Design {
pageName?: string | undefined;
private __titleText = ''; // Alternative method to assign variable
constructor(props?: any, pageName?: string) {
// Initalizes super class for this scope
super(props);
this.pageName = pageName;
}
get titleText(): string {
return this.label1.text || '';
//return this.__titleText;
}
set titleText(value: string) {
this.label1.text = typeof value === 'string' ? value : '';
// E.g. you can check its type to avoid wrong assignments
this.__titleText = typeof value === 'string' ? value : '';
}
static getHeight(): number {
return getCombinedStyle(".listViewItem1").height || 0;
}
}
../components/ListViewItem1.json
{
".listViewItem1": {
"height": 80
}
}

Changing dimensions inside of component on runtime

As stated on Context, you need to call applyLayout when a dimension changes. For iOS, only call this on UI.ListViewItem itself.

Implementing onRowCreate

Note that this is only required if your ListView has more than one type of ListViewItem's.

Untitled
import addChild from "@smartface/contx/lib/smartface/action/addChild";
var itemIndex = 0;
myListView.onRowCreate = function() {
var myListViewItem = new MyLibraryComponent();
this.dispatch(addChild(`item${++itemIndex}`, myListViewItem));
return myListViewItem;
});

Tips & Tricks

scripts/components/ListViewItem1.ts
scripts/components/ListViewItem1.ts
import ListViewItem1Design from 'generated/my-components/ListViewItem1';
export default class ListViewItem1 extends ListViewItem1Design {
pageName?: string | undefined;
private __titleText = ''; // Alternative method to assign variable
constructor(props?: any, pageName?: string) {
// Initalizes super class for this scope
super(props);
this.pageName = pageName;
}
clearText() {
this.label1.text = "";
}
}