Skip to content

Commit 466630a

Browse files
committed
Merge pull request NativeScript#456 from NativeScript/issue-426
The unloaded event of view in the ListView's itemTemplate will now be…
2 parents a4d879f + ac36729 commit 466630a

File tree

9 files changed

+199
-1
lines changed

9 files changed

+199
-1
lines changed

CrossPlatformModules.csproj

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -78,6 +78,9 @@
7878
</TypeScriptCompile>
7979
<TypeScriptCompile Include="apps\action-bar-demo\pages\data-binding.ts">
8080
<DependentUpon>data-binding.xml</DependentUpon>
81+
<TypeScriptCompile Include="apps\list-view-demo\app.ts" />
82+
<TypeScriptCompile Include="apps\list-view-demo\main-page.ts">
83+
<DependentUpon>main-page.xml</DependentUpon>
8184
</TypeScriptCompile>
8285
<TypeScriptCompile Include="apps\cuteness.unoptimized\app.ts" />
8386
<TypeScriptCompile Include="apps\cuteness.unoptimized\details-page.ts">
@@ -94,6 +97,12 @@
9497
<Content Include="apps\action-bar-demo\pages\center-view-segmented.xml" />
9598
<Content Include="apps\action-bar-demo\pages\center-view.xml" />
9699
<Content Include="apps\action-bar-demo\pages\data-binding.xml" />
100+
<Content Include="apps\list-view-demo\another-page.xml">
101+
<SubType>Designer</SubType>
102+
</Content>
103+
<Content Include="apps\list-view-demo\main-page.xml">
104+
<SubType>Designer</SubType>
105+
</Content>
97106
<Content Include="apps\cuteness.unoptimized\reddit-item-view-model.ts" />
98107
<TypeScriptCompile Include="apps\cuteness.unoptimized\reddit-model.d.ts" />
99108
<TypeScriptCompile Include="apps\action-bar-demo\app.ts" />
@@ -1675,6 +1684,9 @@
16751684
<Content Include="apps\action-bar-demo\package.json" />
16761685
<Content Include="fetch\package.json" />
16771686
<Content Include="fetch\README.md" />
1687+
<Content Include="apps\list-view-demo\package.json">
1688+
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
1689+
</Content>
16781690
<None Include="js-libs\esprima\LICENSE.BSD" />
16791691
<Content Include="source-control.md" />
16801692
<Content Include="ui\segmented-bar\package.json">
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
<Page xmlns="http://www.nativescript.org/tns.xsd">
2+
<Label text="Another page"/>
3+
</Page>

apps/list-view-demo/app.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
import application = require("application");
2+
application.mainModule = "main-page";
3+
application.start();

apps/list-view-demo/main-page.ts

Lines changed: 87 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,87 @@
1+
import frame = require("ui/frame");
2+
import observableArray = require("data/observable-array");
3+
4+
var loaded = 0;
5+
var unloaded = 0;
6+
7+
var listView;
8+
var textField;
9+
10+
export function onNavigatedTo(args) {
11+
print();
12+
}
13+
14+
export function onTextFieldLoaded(args) {
15+
textField = args.object;
16+
}
17+
18+
export function onListViewLoaded(args) {
19+
listView = args.object;
20+
console.log("ListView LOADED.");
21+
print();
22+
onBind();
23+
}
24+
25+
export function onListViewUnloaded(args) {
26+
console.log("ListView UNLOADED.");
27+
print();
28+
}
29+
30+
export function onBind() {
31+
var length = textField.text;
32+
console.log("Bind to " + length + " items");
33+
var items = new observableArray.ObservableArray<string>();
34+
var i = 0;
35+
for (; i < length; i++) {
36+
items.push("Item " + i);
37+
}
38+
listView.items = items;
39+
print();
40+
}
41+
42+
export function onAdd() {
43+
var length = textField.text;
44+
console.log("Add " + length + " items");
45+
var i = 0;
46+
for (; i < length; i++) {
47+
var newItem = "Item " + (<observableArray.ObservableArray<string>>listView.items).length;
48+
(<observableArray.ObservableArray<string>>listView.items).push(newItem);
49+
}
50+
print();
51+
}
52+
53+
export function onRemove(s) {
54+
var length = textField.text;
55+
console.log("Remove " + length + " items");
56+
var i = 0;
57+
for (; i < length; i++) {
58+
(<observableArray.ObservableArray<string>>listView.items).splice((<observableArray.ObservableArray<string>>listView.items).length - 1);
59+
}
60+
print();
61+
}
62+
63+
export function onRefresh() {
64+
console.log("Refresh");
65+
listView.refresh();
66+
print();
67+
}
68+
69+
export function onNavigate() {
70+
console.log("Navigate");
71+
frame.topmost().navigate({ moduleName: "./another-page" });
72+
print();
73+
}
74+
75+
export function onViewLoaded(args) {
76+
loaded++;
77+
console.log(args.object.id + args.object._domId + " LOADED");
78+
}
79+
80+
export function onViewUnloaded(args) {
81+
unloaded++;
82+
console.log(args.object.id + args.object._domId + " UNLOADED");
83+
}
84+
85+
export function print() {
86+
console.log("L/U: " + loaded + "/" + unloaded);
87+
}

apps/list-view-demo/main-page.xml

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
<Page xmlns="http://www.nativescript.org/tns.xsd" navigatedTo="onNavigatedTo">
2+
<StackLayout>
3+
<TextField text="1" loaded="onTextFieldLoaded"/>
4+
<Button text="Bind" tap="onBind"/>
5+
<Button text="Add" tap="onAdd"/>
6+
<Button text="Remove" tap="onRemove"/>
7+
<Button text="Refresh" tap="onRefresh"/>
8+
<Button text="Navigate" tap="onNavigate"/>
9+
<ListView loaded="onListViewLoaded" unloaded="onListViewUnloaded">
10+
<ListView.itemTemplate>
11+
<Label text="{{ $value }}" id="label" loaded="onViewLoaded" unloaded="onViewUnloaded" />
12+
</ListView.itemTemplate>
13+
</ListView>
14+
</StackLayout>
15+
</Page>

apps/list-view-demo/package.json

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
{ "name" : "list-view-demo",
2+
"main" : "app.js" }

apps/tests/ui/list-view/list-view-tests.ts

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -684,3 +684,43 @@ function performNativeItemTap(listView: listViewModule.ListView, index: number):
684684
throw new Error("Cannot perform native item tap");
685685
}
686686
}
687+
688+
//export function test_LoadedUnloaded() {
689+
// var listView = new listViewModule.ListView();
690+
// var vm = {
691+
// loadedCount: 0,
692+
// unloadedCount: 0,
693+
// onViewLoaded: function onViewLoaded(args) {
694+
// this.loadedCount++;
695+
// console.log(args.object._domId + " LOADED");
696+
// },
697+
// onViewUnloaded: function onViewUnloaded(args) {
698+
// this.unloadedCount++;
699+
// console.log(args.object._domId + " UNLOADED");
700+
// }
701+
// };
702+
// listView.itemTemplate = "<Label text=\"{{ $value }}\" loaded=\"{{ onViewLoaded }}\" unloaded=\"{{ onViewUnloaded }}\"/>";
703+
// listView.bindingContext = vm;
704+
705+
// var count = 10;
706+
// var modifier = listView.ios ? 1 : 0; // iOS has one fake measure cell that raises loaded.
707+
// var generate = function (count: number): observableArray.ObservableArray<string> {
708+
// var items = new observableArray.ObservableArray<string>();
709+
// for (var i = 0; i < count; i++) {
710+
// items.push("Item " + i);
711+
// }
712+
// return items;
713+
// }
714+
715+
// function testAction(views: Array<viewModule.View>) {
716+
// listView.items = generate(count);
717+
// TKUnit.wait(ASYNC);
718+
// frame.topmost().navigate("pages/navigation/pageB");
719+
// TKUnit.wait(ASYNC);
720+
// frame.topmost().goBack();
721+
// TKUnit.assertEqual(vm.loadedCount, count + modifier, "Loaded Count");
722+
// TKUnit.assertEqual(vm.unloadedCount, count, "Unloaded Count");
723+
// }
724+
725+
// helper.buildUIAndRunTest(listView, testAction);
726+
//}

ui/list-view/list-view.android.ts

Lines changed: 29 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@ export class ListView extends common.ListView {
3636
private _android: android.widget.ListView;
3737
public _realizedItems = {};
3838
private _androidViewId: number;
39+
public _attachStateChangeListener: android.view.View.OnAttachStateChangeListener;
3940

4041
public _createUI() {
4142
this._android = new android.widget.ListView(this._context);
@@ -90,6 +91,28 @@ export class ListView extends common.ListView {
9091
}
9192
}
9293
}));
94+
95+
this._attachStateChangeListener = new android.view.View.OnAttachStateChangeListener({
96+
get owner() {
97+
return that.get();
98+
},
99+
100+
onViewAttachedToWindow: function (view: android.view.View) {
101+
//
102+
},
103+
onViewDetachedFromWindow: function (androidView: android.view.View) {
104+
var owner = that.get();
105+
if (!owner) {
106+
return;
107+
}
108+
109+
var view: viewModule.View = this.owner._realizedItems[androidView.hashCode()];
110+
if (!view) {
111+
return;
112+
}
113+
view.onUnloaded();
114+
}
115+
});
93116
}
94117

95118
get android(): android.widget.ListView {
@@ -213,6 +236,10 @@ class ListViewAdapter extends android.widget.BaseAdapter {
213236
}
214237
}
215238

239+
if (!this._listView._realizedItems[convertView.hashCode()]) {
240+
convertView.addOnAttachStateChangeListener(this._listView._attachStateChangeListener);
241+
}
242+
216243
this._listView._realizedItems[convertView.hashCode()] = args.view;
217244
// cache the realized index (used to raise the ItemLoading event upon scroll stop)
218245
args.view[REALIZED_INDEX] = index;
@@ -222,4 +249,5 @@ class ListViewAdapter extends android.widget.BaseAdapter {
222249

223250
return convertView;
224251
}
225-
}
252+
}
253+

ui/list-view/list-view.ios.ts

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,14 @@ class ListViewCell extends UITableViewCell {
2323
static new(): ListViewCell {
2424
return <ListViewCell>super.new();
2525
}
26+
27+
public removeFromSuperview(): void {
28+
super.removeFromSuperview();
29+
var view: view.View = (<any>this).view;
30+
if (view) {
31+
view.onUnloaded();
32+
}
33+
}
2634
}
2735

2836
function notifyForItemAtIndex(listView: definition.ListView, cell: any, eventName: string, indexPath: NSIndexPath) {

0 commit comments

Comments
 (0)