From 0f45a0df5ecbf1ddc2cea831b4a4d5ece8da6783 Mon Sep 17 00:00:00 2001 From: Hristo Hristov Date: Tue, 29 Nov 2016 01:32:52 +0200 Subject: [PATCH] list-view progress --- tns-core-modules/ui/core/view.d.ts | 7 +- .../ui/list-view/list-view-common.ts | 304 ++++++------------ .../ui/list-view/list-view.android.ts | 164 +++++----- tns-core-modules/ui/list-view/list-view.d.ts | 83 ++--- .../ui/list-view/list-view.ios.ts | 18 +- 5 files changed, 233 insertions(+), 343 deletions(-) diff --git a/tns-core-modules/ui/core/view.d.ts b/tns-core-modules/ui/core/view.d.ts index db884b7e1..a5addd251 100644 --- a/tns-core-modules/ui/core/view.d.ts +++ b/tns-core-modules/ui/core/view.d.ts @@ -329,6 +329,11 @@ declare module "ui/core/view" { cssClasses: Set; cssPseudoClasses: Set; + /** + * Gets the parent view. This property is read-only. + */ + public parent: View; + /** * Gets owner page. This is a read-only property. */ @@ -776,7 +781,7 @@ declare module "ui/core/view" { export const fontFamilyProperty: InheritedCssProperty; export const fontStyleProperty: InheritedCssProperty; export const fontWeightProperty: InheritedCssProperty; - + export const backgroundInternalProperty: CssProperty; export const fontInternalProperty: InheritedCssProperty; } \ No newline at end of file diff --git a/tns-core-modules/ui/list-view/list-view-common.ts b/tns-core-modules/ui/list-view/list-view-common.ts index 99fc81da8..1c3b54f51 100644 --- a/tns-core-modules/ui/list-view/list-view-common.ts +++ b/tns-core-modules/ui/list-view/list-view-common.ts @@ -1,224 +1,72 @@ -import observable = require("data/observable"); -import view = require("ui/core/view"); -import proxy = require("ui/core/proxy"); -import definition = require("ui/list-view"); -import dependencyObservable = require("ui/core/dependency-observable"); -import color = require("color"); -import * as builderModule from "ui/builder"; -import * as labelModule from "ui/label"; -import * as observableArrayModule from "data/observable-array"; -import * as weakEventsModule from "ui/core/weak-event-listener"; -import {isString, isFunction} from "utils/types"; +import { ListView as ListViewDefinition, ItemsSource } from "ui/list-view"; +import { EventData, Observable } from "data/observable"; +import { View, Template, KeyedTemplate } from "ui/core/view"; +import { Property } from "ui/core/properties"; +import { Color } from "color"; + +import { parse, parseMultipleTemplates } from "ui/builder"; +import { Label } from "ui/label"; +import { ObservableArray } from "data/observable-array"; +import { addWeakEventListener, removeWeakEventListener } from "ui/core/weak-event-listener"; import { Bindable } from "ui/core/bindable"; -var builder: typeof builderModule; -function ensureBuilder() { - if (!builder) { - builder = require("ui/builder"); - } -} - -var label: typeof labelModule; -function ensureLabel() { - if (!label) { - label = require("ui/label"); - } -} - -var observableArray: typeof observableArrayModule; -function ensureObservableArray() { - if (!observableArray) { - observableArray = require("data/observable-array"); - } -} - -var weakEvents: typeof weakEventsModule; -function ensureWeakEvents() { - if (!weakEvents) { - weakEvents = require("ui/core/weak-event-listener"); - } -} - -var ITEMS = "items"; -var ITEMTEMPLATE = "itemTemplate"; -var ITEMTEMPLATES = "itemTemplates"; -var ISSCROLLING = "isScrolling"; -var LISTVIEW = "ListView"; -var SEPARATORCOLOR = "separatorColor"; -var ROWHEIGHT = "rowHeight"; - +// TODO: Think of a way to register these instead of relying on hardcoded values. export module knownTemplates { - export var itemTemplate = "itemTemplate"; + export let itemTemplate = "itemTemplate"; } export module knownMultiTemplates { - export var itemTemplates = "itemTemplates"; + export let itemTemplates = "itemTemplates"; } -function onItemsPropertyChanged(data: dependencyObservable.PropertyChangeData) { - var listView = data.object; - listView._onItemsPropertyChanged(data); -} - -function onItemTemplatePropertyChanged(data: dependencyObservable.PropertyChangeData) { - var listView = data.object; - listView.refresh(); -} - -function onItemTemplatesPropertyChanged(data: dependencyObservable.PropertyChangeData) { - var listView = data.object; - listView._onItemTemplatesPropertyChanged(data); -} - -function onRowHeightPropertyChanged(data: dependencyObservable.PropertyChangeData) { - var listView = data.object; - listView._onRowHeightPropertyChanged(data); -} - -export class ListView extends view.View implements definition.ListView { +export abstract class ListViewBase extends View implements ListViewDefinition { public static itemLoadingEvent = "itemLoading"; public static itemTapEvent = "itemTap"; public static loadMoreItemsEvent = "loadMoreItems"; + // TODO: get rid of such hacks. public static knownFunctions = ["itemTemplateSelector"]; //See component-builder.ts isKnownFunction - + private _itemTemplateSelector: (item: any, index: number, items: any) => string; private _itemTemplateSelectorBindable = new Bindable(); - public _defaultTemplate: view.KeyedTemplate = { + public _defaultTemplate: KeyedTemplate = { key: "default", createView: () => { if (this.itemTemplate) { - ensureBuilder(); - return builder.parse(this.itemTemplate, this); + return parse(this.itemTemplate, this); } return undefined; } } - public _itemTemplatesInternal = new Array(this._defaultTemplate); - public static separatorColorProperty = new dependencyObservable.Property( - SEPARATORCOLOR, - LISTVIEW, - new proxy.PropertyMetadata(undefined)); + public _itemTemplatesInternal = new Array(this._defaultTemplate); - public static itemsProperty = new dependencyObservable.Property( - ITEMS, - LISTVIEW, - new proxy.PropertyMetadata( - undefined, - dependencyObservable.PropertyMetadataSettings.AffectsLayout, - onItemsPropertyChanged - ) - ); - - public static itemTemplateProperty = new dependencyObservable.Property( - ITEMTEMPLATE, - LISTVIEW, - new proxy.PropertyMetadata( - undefined, - dependencyObservable.PropertyMetadataSettings.AffectsLayout, - onItemTemplatePropertyChanged - ) - ); - - public static itemTemplatesProperty = new dependencyObservable.Property( - ITEMTEMPLATES, - LISTVIEW, - new proxy.PropertyMetadata( - undefined, - dependencyObservable.PropertyMetadataSettings.AffectsLayout, - onItemTemplatesPropertyChanged - ) - ); - - public static isScrollingProperty = new dependencyObservable.Property( - ISSCROLLING, - LISTVIEW, - new proxy.PropertyMetadata( - false, - dependencyObservable.PropertyMetadataSettings.None - ) - ); - - public static rowHeightProperty = new dependencyObservable.Property( - ROWHEIGHT, - LISTVIEW, - new proxy.PropertyMetadata( - -1, - dependencyObservable.PropertyMetadataSettings.AffectsLayout, - onRowHeightPropertyChanged - ) - ); - - get items(): any { - return this._getValue(ListView.itemsProperty); - } - set items(value: any) { - this._setValue(ListView.itemsProperty, value); - } - - get itemTemplate(): string | view.Template { - return this._getValue(ListView.itemTemplateProperty); - } - set itemTemplate(value: string | view.Template) { - this._setValue(ListView.itemTemplateProperty, value); - } - - get itemTemplates(): string | Array { - return this._getValue(ListView.itemTemplatesProperty); - } - set itemTemplates(value: string | Array) { - let newValue = value; - if (isString(newValue)){ - ensureBuilder(); - newValue = builder.parseMultipleTemplates(newValue, this); - } - this._setValue(ListView.itemTemplatesProperty, newValue); - } + public rowHeight: number; + public separatorColor: Color; + public items: any[] | ItemsSource; + public itemTemplate: string | Template; + public itemTemplates: string | Array; get itemTemplateSelector(): string | ((item: any, index: number, items: any) => string) { return this._itemTemplateSelector; } - set itemTemplateSelector(value: string | ((item: any, index: number, items: any) => string)) { - if (isString(value)){ + if (typeof value === "string") { this._itemTemplateSelectorBindable.bind({ sourceProperty: null, targetProperty: "templateKey", - expression: value + expression: value }); this._itemTemplateSelector = (item: any, index: number, items: any) => { item["$index"] = index; this._itemTemplateSelectorBindable.bindingContext = item; - return this._itemTemplateSelectorBindable.get("templateKey"); + return this._itemTemplateSelectorBindable.get("templateKey"); }; } - else if (isFunction(value)) { - this._itemTemplateSelector = <((item: any, index: number, items: any) => string)>value; + else if (typeof value === "function") { + this._itemTemplateSelector = value; } } - get isScrolling(): boolean { - return false; - } - set isScrolling(value: boolean) { - // Do nothing. - } - - get separatorColor(): color.Color { - return this.style._getValue(ListView.separatorColorProperty); - } - set separatorColor(value: color.Color) { - this.style._setValue(ListView.separatorColorProperty, - value instanceof color.Color ? value : new color.Color(value)); - } - - get rowHeight(): number { - return this._getValue(ListView.rowHeightProperty); - } - set rowHeight(value: number) { - this._setValue(ListView.rowHeightProperty, value); - } - public refresh() { // } @@ -227,69 +75,107 @@ export class ListView extends view.View implements definition.ListView { // } - public _getItemTemplate(index: number): view.KeyedTemplate { + public _getItemTemplate(index: number): KeyedTemplate { let templateKey = "default"; - if (this.itemTemplateSelector){ + if (this.itemTemplateSelector) { let dataItem = this._getDataItem(index); templateKey = this._itemTemplateSelector(dataItem, index, this.items); } for (let i = 0, length = this._itemTemplatesInternal.length; i < length; i++) { - if (this._itemTemplatesInternal[i].key === templateKey){ + if (this._itemTemplatesInternal[i].key === templateKey) { return this._itemTemplatesInternal[i]; } } // This is the default template - return this._itemTemplatesInternal[0]; + return this._itemTemplatesInternal[0]; } - - public _prepareItem(item: view.View, index: number) { + + public _prepareItem(item: View, index: number) { if (item) { item.bindingContext = this._getDataItem(index); } } private _getDataItem(index: number): any { - let thisItems = this.items; + let thisItems = this.items; return thisItems.getItem ? thisItems.getItem(index) : thisItems[index]; } - public _getDefaultItemContent(index: number): view.View { - ensureLabel(); - - var lbl = new label.Label(); + public _getDefaultItemContent(index: number): View { + let lbl = new Label(); lbl.bind({ targetProperty: "text", sourceProperty: "$value" - }); + }, null); return lbl; } - public _onItemsPropertyChanged(data: dependencyObservable.PropertyChangeData) { - ensureObservableArray(); - ensureWeakEvents(); + public _onItemsChanged(args: EventData) { + this.refresh(); + } - if (data.oldValue instanceof observable.Observable) { - weakEvents.removeWeakEventListener(data.oldValue, observableArray.ObservableArray.changeEvent, this._onItemsChanged, this); + public _onRowHeightPropertyChanged(oldValue: number, newValue: number) { + this.refresh(); + } +} + +/** + * Represents the property backing the items property of each ListView instance. + */ +export const itemsProperty = new Property({ + name: "items", valueChanged: (target, oldValue, newValue) => { + if (oldValue instanceof Observable) { + removeWeakEventListener(oldValue, ObservableArray.changeEvent, target._onItemsChanged, target); } - if (data.newValue instanceof observable.Observable) { - weakEvents.addWeakEventListener(data.newValue, observableArray.ObservableArray.changeEvent, this._onItemsChanged, this); + if (newValue instanceof Observable) { + addWeakEventListener(newValue, ObservableArray.changeEvent, target._onItemsChanged, target); } - this.refresh(); + target.refresh(); } +}); - private _onItemsChanged(args: observable.EventData) { - this.refresh(); +/** + * Represents the item template property of each ListView instance. + */ +export const itemTemplateProperty = new Property({ + name: "itemTemplate", valueChanged: (target) => { + target.refresh(); } +}); - public _onRowHeightPropertyChanged(data: dependencyObservable.PropertyChangeData) { - this.refresh(); - } +/** + * Represents the items template property of each ListView instance. + */ +export const itemTemplatesProperty = new Property>({ + name: "itemTemplates", valueConverter: (value) => { + if (typeof value === "string") { + return parseMultipleTemplates(value); + } - public _onItemTemplatesPropertyChanged(data: dependencyObservable.PropertyChangeData) { - // + return value; } -} \ No newline at end of file +}) + +/** + * Represents the separator color backing property. + */ +export const separatorColor = new Property({ + name: "separatorColor", valueConverter: (value) => { + if (typeof value === "string") { + return new Color(value); + } + + return value; + } +}) + +/** + * Represents the observable property backing the rowHeight property of each ListView instance. + */ +export const rowHeightProperty = new Property({ + name: "rowHeight", defaultValue: -1, valueChanged: (target, oldValue, newValue) => target._onRowHeightPropertyChanged(oldValue, newValue) +}); diff --git a/tns-core-modules/ui/list-view/list-view.android.ts b/tns-core-modules/ui/list-view/list-view.android.ts index 67b4c51ec..da23674a4 100644 --- a/tns-core-modules/ui/list-view/list-view.android.ts +++ b/tns-core-modules/ui/list-view/list-view.android.ts @@ -1,50 +1,41 @@ -import observable = require("data/observable"); -import common = require("./list-view-common"); -import viewModule = require("ui/core/view"); -import stackLayout = require("ui/layouts/stack-layout"); -import proxy = require("ui/core/proxy"); -import dependencyObservable = require("ui/core/dependency-observable"); -import definition = require("ui/list-view"); -import {ProxyViewContainer} from "ui/proxy-view-container"; -import * as layoutBase from "ui/layouts/layout-base"; -import * as colorModule from "color"; -import { separatorColorProperty, registerHandler, Styler, StylePropertyChangedHandler } from "ui/styling/style"; +import { ItemEventData, ItemsSource } from "ui/list-view"; +import { ListViewBase, separatorColor, itemTemplatesProperty } from "./list-view-common"; +import { View, KeyedTemplate } from "ui/core/view"; +import { Property } from "ui/core/properties"; +import { unsetValue } from "ui/core/dependency-observable"; +import { Observable } from "data/observable"; +import { StackLayout } from "ui/layouts/stack-layout"; +import { ProxyViewContainer } from "ui/proxy-view-container"; +import { LayoutBase } from "ui/layouts/layout-base"; +import { Color } from "color"; -let color: typeof colorModule; -function ensureColor() { - if (!color) { - color = require("color"); +export * from "./list-view-common"; + +let ITEMLOADING = ListViewBase.itemLoadingEvent; +let LOADMOREITEMS = ListViewBase.loadMoreItemsEvent; +let ITEMTAP = ListViewBase.itemTapEvent; + +@Interfaces([]) +class ItemClickListener implements android.widget.AdapterView.OnItemClickListener { + constructor(private owner: WeakRef) { + return global.__native(this); + } + + onItemClick(parent: android.widget.AdapterView, convertView: android.view.View, index: number, id: number) { + let owner = this.owner.get(); + if (owner) { + let view = owner._realizedTemplates.get(owner._getItemTemplate(index).key).get(convertView); + owner.notify({ eventName: ITEMTAP, object: owner, index: index, view: view }); + } } } -let ITEMLOADING = common.ListView.itemLoadingEvent; -let LOADMOREITEMS = common.ListView.loadMoreItemsEvent; -let ITEMTAP = common.ListView.itemTapEvent; - -global.moduleMerge(common, exports); - -function onSeparatorColorPropertyChanged(data: dependencyObservable.PropertyChangeData) { - let listView = data.object; - if (!listView.android) { - return; - } - - ensureColor(); - - if (data.newValue instanceof color.Color) { - listView.android.setDivider(new android.graphics.drawable.ColorDrawable(data.newValue.android)); - listView.android.setDividerHeight(1); - } -} - -// register the setNativeValue callbacks -(common.ListView.separatorColorProperty.metadata).onSetNativeValue = onSeparatorColorPropertyChanged; - -export class ListView extends common.ListView { +export class ListView extends ListViewBase { private _androidViewId: number = -1; private _android: android.widget.ListView; - public _realizedItems = new Map(); - public _realizedTemplates = new Map>(); + private _itemClickListener: android.widget.AdapterView.OnItemClickListener; + public _realizedItems = new Map(); + public _realizedTemplates = new Map>(); public _createUI() { this._android = new android.widget.ListView(this._context); @@ -61,15 +52,8 @@ export class ListView extends common.ListView { this.android.setAdapter(new ListViewAdapterClass(this)); let that = new WeakRef(this); - this.android.setOnItemClickListener(new android.widget.AdapterView.OnItemClickListener({ - onItemClick: function (parent: any, convertView: android.view.View, index: number, id: number) { - let owner = that.get(); - if (owner) { - let view = owner._realizedTemplates.get(owner._getItemTemplate(index).key).get(convertView); - owner.notify({ eventName: ITEMTAP, object: owner, index: index, view: view }); - } - } - })); + this._itemClickListener = this._itemClickListener || new ItemClickListener(new WeakRef(this)); + this.android.setOnItemClickListener(this._itemClickListener); } get android(): android.widget.ListView { @@ -82,12 +66,12 @@ export class ListView extends common.ListView { } // clear bindingContext when it is not observable because otherwise bindings to items won't reevaluate - this._realizedItems.forEach((view, nativeView, map) => { - if (!(view.bindingContext instanceof observable.Observable)) { + this._realizedItems.forEach((view, nativeView, map) => { + if (!(view.bindingContext instanceof Observable)) { view.bindingContext = null; } }); - + (this.android.getAdapter()).notifyDataSetChanged(); } @@ -106,7 +90,7 @@ export class ListView extends common.ListView { return this._realizedItems.size; } - public _eachChildView(callback: (child: viewModule.View) => boolean): void { + public _eachChildView(callback: (child: View) => boolean): void { this._realizedItems.forEach((view, nativeView, map) => { if (view.parent instanceof ListView) { callback(view); @@ -120,16 +104,16 @@ export class ListView extends common.ListView { }); } - public _dumpRealizedTemplates(){ - console.log(`Realized Templates:`); + public _dumpRealizedTemplates() { + console.log(`Realized Templates:`); this._realizedTemplates.forEach((value, index, map) => { console.log(`\t${index}:`); value.forEach((value, index, map) => { console.log(`\t\t${index.hashCode()}: ${value}`); }); }); - console.log(`Realized Items Size: ${this._realizedItems.size}`); - } + console.log(`Realized Items Size: ${this._realizedItems.size}`); + } private clearRealizedCells(): void { // clear the cache @@ -147,17 +131,30 @@ export class ListView extends common.ListView { this._realizedTemplates.clear(); } - public _onItemTemplatesPropertyChanged(data: dependencyObservable.PropertyChangeData) { - this._itemTemplatesInternal = new Array(this._defaultTemplate); - if (data.newValue){ - this._itemTemplatesInternal = this._itemTemplatesInternal.concat(data.newValue); + get [separatorColor.native](): number { + return null; + } + set [separatorColor.native](value: Color) { + let nativeView = this._android; + if (value) { + nativeView.setDivider(new android.graphics.drawable.ColorDrawable(value.android)); + nativeView.setDividerHeight(1); + } else { + nativeView.setDivider(null); + nativeView.setDividerHeight(0); } - - if (this.android){ - ensureListViewAdapterClass(); - this.android.setAdapter(new ListViewAdapterClass(this)); + } + + get [itemTemplatesProperty.native](): KeyedTemplate[] { + return null; + } + set [itemTemplatesProperty.native](value: KeyedTemplate[]) { + this._itemTemplatesInternal = new Array(this._defaultTemplate); + if (value) { + this._itemTemplatesInternal = this._itemTemplatesInternal.concat(value); } - + + this.android.setAdapter(new ListViewAdapterClass(this)); this.refresh(); } } @@ -173,9 +170,7 @@ function ensureListViewAdapterClass() { constructor(listView: ListView) { super(); - this._listView = listView; - return global.__native(this); } @@ -185,7 +180,8 @@ function ensureListViewAdapterClass() { public getItem(i: number) { if (this._listView && this._listView.items && i < this._listView.items.length) { - return this._listView.items.getItem ? this._listView.items.getItem(i) : this._listView.items[i]; + let getItem = (this._listView.items).getItem + return getItem ? getItem(i) : this._listView.items[i]; } return null; @@ -200,7 +196,7 @@ function ensureListViewAdapterClass() { } public getViewTypeCount() { - return this._listView._itemTemplatesInternal.length; + return this._listView._itemTemplatesInternal.length; } public getItemViewType(index: number) { @@ -208,10 +204,10 @@ function ensureListViewAdapterClass() { let itemViewType = this._listView._itemTemplatesInternal.indexOf(template); return itemViewType; } - + public getView(index: number, convertView: android.view.View, parent: android.view.ViewGroup): android.view.View { //this._listView._dumpRealizedTemplates(); - + if (!this._listView) { return null; } @@ -223,10 +219,10 @@ function ensureListViewAdapterClass() { // Recycle an existing view or create a new one if needed. let template = this._listView._getItemTemplate(index); - let view: viewModule.View; - if (convertView){ + let view: View; + if (convertView) { view = this._listView._realizedTemplates.get(template.key).get(convertView); - if (!view){ + if (!view) { throw new Error(`There is no entry with key '${convertView}' in the realized views cache for template with key'${template.key}'.`); } } @@ -234,7 +230,7 @@ function ensureListViewAdapterClass() { view = template.createView(); } - let args: definition.ItemEventData = { + let args: ItemEventData = { eventName: ITEMLOADING, object: this._listView, index: index, view: view, android: parent, ios: undefined @@ -251,19 +247,19 @@ function ensureListViewAdapterClass() { args.view.height = this._listView.rowHeight; } else { - args.view.height = Number.NaN; + args.view.height = unsetValue; } this._listView._prepareItem(args.view, index); if (!args.view.parent) { // Proxy containers should not get treated as layouts. // Wrap them in a real layout as well. - if (args.view instanceof layoutBase.LayoutBase && + if (args.view instanceof LayoutBase && !(args.view instanceof ProxyViewContainer)) { this._listView._addView(args.view); convertView = args.view.android; } else { - let sp = new stackLayout.StackLayout(); + let sp = new StackLayout(); sp.addChild(args.view); this._listView._addView(sp); @@ -273,10 +269,10 @@ function ensureListViewAdapterClass() { // Cache the view for recycling let realizedItemsForTemplateKey = this._listView._realizedTemplates.get(template.key); - if (!realizedItemsForTemplateKey){ - realizedItemsForTemplateKey = new Map(); + if (!realizedItemsForTemplateKey) { + realizedItemsForTemplateKey = new Map(); this._listView._realizedTemplates.set(template.key, realizedItemsForTemplateKey); - } + } realizedItemsForTemplateKey.set(convertView, args.view); this._listView._realizedItems.set(convertView, args.view); } @@ -309,4 +305,4 @@ export class ListViewStyler implements Styler { } } -ListViewStyler.registerHandlers(); \ No newline at end of file +ListViewStyler.registerHandlers(); diff --git a/tns-core-modules/ui/list-view/list-view.d.ts b/tns-core-modules/ui/list-view/list-view.d.ts index 1958c1351..2d9edd9e6 100644 --- a/tns-core-modules/ui/list-view/list-view.d.ts +++ b/tns-core-modules/ui/list-view/list-view.d.ts @@ -2,10 +2,10 @@ * Contains the ListView class, which represents a standard list view widget. */ declare module "ui/list-view" { - import observable = require("data/observable"); - import dependencyObservable = require("ui/core/dependency-observable"); - import view = require("ui/core/view"); - import color = require("color"); + import { EventData } from "data/observable"; + import { View, Template, KeyedTemplate } from "ui/core/view"; + import { Property } from "ui/core/properties"; + import { Color } from "color"; /** * Known template names. @@ -20,7 +20,7 @@ declare module "ui/list-view" { /** * Represents a view that shows items in a vertically scrolling list. */ - export class ListView extends view.View { + export class ListView extends View { /** * String value used when hooking to itemLoading event. */ @@ -34,27 +34,6 @@ declare module "ui/list-view" { */ public static loadMoreItemsEvent: string; - /** - * Represents the observable property backing the items property of each ListView instance. - */ - public static itemsProperty: dependencyObservable.Property; - - /** - * Represents the item template property of each ListView instance. - */ - public static itemTemplateProperty: dependencyObservable.Property; - - /** - * Represents the observable property backing the isScrolling property of each ListView instance. - */ - @Deprecated // in 2.1 - public static isScrollingProperty: dependencyObservable.Property; - - /** - * Represents the observable property backing the rowHeight property of each ListView instance. - */ - public static rowHeightProperty: dependencyObservable.Property; - /** * Gets the native [android widget](http://developer.android.com/reference/android/widget/ListView.html) that represents the user interface for this component. Valid only when running on Android OS. */ @@ -65,27 +44,21 @@ declare module "ui/list-view" { */ ios: any /* UITableView */; - /** - * Gets a value indicating whether the ListView is currently scrolling. - */ - @Deprecated // in 2.1 - isScrolling: boolean; - /** * 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. */ - items: any; + items: any[] | ItemsSource; /** * Gets or set the item template of the ListView. */ - itemTemplate: string | view.Template; + itemTemplate: string | Template; /** * Gets or set the list of item templates for the item template selector */ - itemTemplates: string | Array; + itemTemplates: string | Array; /** * A function that returns the appropriate ket template based on the data item. @@ -95,7 +68,7 @@ declare module "ui/list-view" { /** * Gets or set the items separator line color of the ListView. */ - separatorColor: color.Color; + separatorColor: Color; /** * Gets or set row height of the ListView. @@ -121,7 +94,7 @@ declare module "ui/list-view" { * @param callback - Callback function which will be executed when event is raised. * @param thisArg - An optional parameter which will be used as `this` context for callback execution. */ - on(eventNames: string, callback: (data: observable.EventData) => void, thisArg?: any); + on(eventNames: string, callback: (data: EventData) => void, thisArg?: any); /** * Raised when a View for the data at the specified index should be created. @@ -139,13 +112,13 @@ declare module "ui/list-view" { /** * Raised when the ListView is scrolled so that its last item is visible. */ - on(event: "loadMoreItems", callback: (args: observable.EventData) => void, thisArg?: any); + on(event: "loadMoreItems", callback: (args: EventData) => void, thisArg?: any); } /** * Event data containing information for the index and the view associated to a list view item. */ - export interface ItemEventData extends observable.EventData { + export interface ItemEventData extends EventData { /** * The index of the item, for which the event is raised. */ @@ -154,7 +127,7 @@ declare module "ui/list-view" { /** * The view that is associated to the item, for which the event is raised. */ - view: view.View; + view: View; /** * Gets the native [iOS view](https://developer.apple.com/library/ios/documentation/UIKit/Reference/UITableViewCell_Class/) that represents the user interface where the view is hosted. Valid only when running on iOS. @@ -166,4 +139,34 @@ declare module "ui/list-view" { */ android: any /* android.view.ViewGroup */; } + + export interface ItemsSource { + length: number; + getItem(index: number): any; + } + + /** + * Represents the property backing the items property of each ListView instance. + */ + export const itemsProperty: Property; + + /** + * Represents the item template property of each ListView instance. + */ + export const itemTemplateProperty: Property; + + /** + * Represents the items template property of each ListView instance. + */ + export const itemTemplatesProperty: Property>; + + /** + * Represents the separator color backing property. + */ + export const separatorColor: Property; + + /** + * Represents the observable property backing the rowHeight property of each ListView instance. + */ + export const rowHeightProperty: Property; } diff --git a/tns-core-modules/ui/list-view/list-view.ios.ts b/tns-core-modules/ui/list-view/list-view.ios.ts index b48a3da6a..1968b18b9 100644 --- a/tns-core-modules/ui/list-view/list-view.ios.ts +++ b/tns-core-modules/ui/list-view/list-view.ios.ts @@ -214,8 +214,8 @@ export class ListView extends common.ListView { private _dataSource; private _delegate; private _heights: Array; - private _preparingCell: boolean = false; - private _isDataDirty: boolean = false; + private _preparingCell: boolean; + private _isDataDirty: boolean; private _map: Map; public _rowHeight: number = -1; widthMeasureSpec: number = 0; @@ -233,7 +233,7 @@ export class ListView extends common.ListView { this._map = new Map(); } - public _onItemTemplatesPropertyChanged(data: dependencyObservable.PropertyChangeData) { + protected _onItemTemplatesPropertyChanged(data: dependencyObservable.PropertyChangeData) { this._itemTemplatesInternal = new Array(this._defaultTemplate); if (data.newValue) { for(let i = 0, length = data.newValue.length; i < length; i++){ @@ -304,16 +304,16 @@ export class ListView extends common.ListView { this._heights[index] = value; } - public _onRowHeightPropertyChanged(data: dependencyObservable.PropertyChangeData) { - this._rowHeight = data.newValue; - if (data.newValue < 0) { + public _onRowHeightPropertyChanged(oldValue: number, newValue: number) { + this._rowHeight = newValue; + if (newValue < 0) { this._nativeView.rowHeight = UITableViewAutomaticDimension; this._nativeView.estimatedRowHeight = DEFAULT_HEIGHT; this._delegate = UITableViewDelegateImpl.initWithOwner(new WeakRef(this)); } else { - this._nativeView.rowHeight = data.newValue; - this._nativeView.estimatedRowHeight = data.newValue; + this._nativeView.rowHeight = newValue; + this._nativeView.estimatedRowHeight = newValue; this._delegate = UITableViewRowHeightDelegateImpl.initWithOwner(new WeakRef(this)); } @@ -321,7 +321,7 @@ export class ListView extends common.ListView { this._nativeView.delegate = this._delegate; } - super._onRowHeightPropertyChanged(data); + super._onRowHeightPropertyChanged(oldValue, newValue); } public requestLayout(): void {