mirror of
https://github.com/NativeScript/NativeScript.git
synced 2025-11-05 13:26:48 +08:00
The unloaded event of view in the ListView's itemTemplate will now be called when its underlying native view is removed from the visual tree. When this happens is beyond our control.
This commit is contained in:
@@ -78,6 +78,9 @@
|
||||
</TypeScriptCompile>
|
||||
<TypeScriptCompile Include="apps\action-bar-demo\pages\data-binding.ts">
|
||||
<DependentUpon>data-binding.xml</DependentUpon>
|
||||
<TypeScriptCompile Include="apps\list-view-demo\app.ts" />
|
||||
<TypeScriptCompile Include="apps\list-view-demo\main-page.ts">
|
||||
<DependentUpon>main-page.xml</DependentUpon>
|
||||
</TypeScriptCompile>
|
||||
<TypeScriptCompile Include="apps\cuteness.unoptimized\app.ts" />
|
||||
<TypeScriptCompile Include="apps\cuteness.unoptimized\details-page.ts">
|
||||
@@ -94,6 +97,12 @@
|
||||
<Content Include="apps\action-bar-demo\pages\center-view-segmented.xml" />
|
||||
<Content Include="apps\action-bar-demo\pages\center-view.xml" />
|
||||
<Content Include="apps\action-bar-demo\pages\data-binding.xml" />
|
||||
<Content Include="apps\list-view-demo\another-page.xml">
|
||||
<SubType>Designer</SubType>
|
||||
</Content>
|
||||
<Content Include="apps\list-view-demo\main-page.xml">
|
||||
<SubType>Designer</SubType>
|
||||
</Content>
|
||||
<Content Include="apps\cuteness.unoptimized\reddit-item-view-model.ts" />
|
||||
<TypeScriptCompile Include="apps\cuteness.unoptimized\reddit-model.d.ts" />
|
||||
<TypeScriptCompile Include="apps\action-bar-demo\app.ts" />
|
||||
@@ -1675,6 +1684,9 @@
|
||||
<Content Include="apps\action-bar-demo\package.json" />
|
||||
<Content Include="fetch\package.json" />
|
||||
<Content Include="fetch\README.md" />
|
||||
<Content Include="apps\list-view-demo\package.json">
|
||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||
</Content>
|
||||
<None Include="js-libs\esprima\LICENSE.BSD" />
|
||||
<Content Include="source-control.md" />
|
||||
<Content Include="ui\segmented-bar\package.json">
|
||||
|
||||
3
apps/list-view-demo/another-page.xml
Normal file
3
apps/list-view-demo/another-page.xml
Normal file
@@ -0,0 +1,3 @@
|
||||
<Page xmlns="http://www.nativescript.org/tns.xsd">
|
||||
<Label text="Another page"/>
|
||||
</Page>
|
||||
3
apps/list-view-demo/app.ts
Normal file
3
apps/list-view-demo/app.ts
Normal file
@@ -0,0 +1,3 @@
|
||||
import application = require("application");
|
||||
application.mainModule = "main-page";
|
||||
application.start();
|
||||
87
apps/list-view-demo/main-page.ts
Normal file
87
apps/list-view-demo/main-page.ts
Normal file
@@ -0,0 +1,87 @@
|
||||
import frame = require("ui/frame");
|
||||
import observableArray = require("data/observable-array");
|
||||
|
||||
var loaded = 0;
|
||||
var unloaded = 0;
|
||||
|
||||
var listView;
|
||||
var textField;
|
||||
|
||||
export function onNavigatedTo(args) {
|
||||
print();
|
||||
}
|
||||
|
||||
export function onTextFieldLoaded(args) {
|
||||
textField = args.object;
|
||||
}
|
||||
|
||||
export function onListViewLoaded(args) {
|
||||
listView = args.object;
|
||||
console.log("ListView LOADED.");
|
||||
print();
|
||||
onBind();
|
||||
}
|
||||
|
||||
export function onListViewUnloaded(args) {
|
||||
console.log("ListView UNLOADED.");
|
||||
print();
|
||||
}
|
||||
|
||||
export function onBind() {
|
||||
var length = textField.text;
|
||||
console.log("Bind to " + length + " items");
|
||||
var items = new observableArray.ObservableArray<string>();
|
||||
var i = 0;
|
||||
for (; i < length; i++) {
|
||||
items.push("Item " + i);
|
||||
}
|
||||
listView.items = items;
|
||||
print();
|
||||
}
|
||||
|
||||
export function onAdd() {
|
||||
var length = textField.text;
|
||||
console.log("Add " + length + " items");
|
||||
var i = 0;
|
||||
for (; i < length; i++) {
|
||||
var newItem = "Item " + (<observableArray.ObservableArray<string>>listView.items).length;
|
||||
(<observableArray.ObservableArray<string>>listView.items).push(newItem);
|
||||
}
|
||||
print();
|
||||
}
|
||||
|
||||
export function onRemove(s) {
|
||||
var length = textField.text;
|
||||
console.log("Remove " + length + " items");
|
||||
var i = 0;
|
||||
for (; i < length; i++) {
|
||||
(<observableArray.ObservableArray<string>>listView.items).splice((<observableArray.ObservableArray<string>>listView.items).length - 1);
|
||||
}
|
||||
print();
|
||||
}
|
||||
|
||||
export function onRefresh() {
|
||||
console.log("Refresh");
|
||||
listView.refresh();
|
||||
print();
|
||||
}
|
||||
|
||||
export function onNavigate() {
|
||||
console.log("Navigate");
|
||||
frame.topmost().navigate({ moduleName: "./another-page" });
|
||||
print();
|
||||
}
|
||||
|
||||
export function onViewLoaded(args) {
|
||||
loaded++;
|
||||
console.log(args.object.id + args.object._domId + " LOADED");
|
||||
}
|
||||
|
||||
export function onViewUnloaded(args) {
|
||||
unloaded++;
|
||||
console.log(args.object.id + args.object._domId + " UNLOADED");
|
||||
}
|
||||
|
||||
export function print() {
|
||||
console.log("L/U: " + loaded + "/" + unloaded);
|
||||
}
|
||||
15
apps/list-view-demo/main-page.xml
Normal file
15
apps/list-view-demo/main-page.xml
Normal file
@@ -0,0 +1,15 @@
|
||||
<Page xmlns="http://www.nativescript.org/tns.xsd" navigatedTo="onNavigatedTo">
|
||||
<StackLayout>
|
||||
<TextField text="1" loaded="onTextFieldLoaded"/>
|
||||
<Button text="Bind" tap="onBind"/>
|
||||
<Button text="Add" tap="onAdd"/>
|
||||
<Button text="Remove" tap="onRemove"/>
|
||||
<Button text="Refresh" tap="onRefresh"/>
|
||||
<Button text="Navigate" tap="onNavigate"/>
|
||||
<ListView loaded="onListViewLoaded" unloaded="onListViewUnloaded">
|
||||
<ListView.itemTemplate>
|
||||
<Label text="{{ $value }}" id="label" loaded="onViewLoaded" unloaded="onViewUnloaded" />
|
||||
</ListView.itemTemplate>
|
||||
</ListView>
|
||||
</StackLayout>
|
||||
</Page>
|
||||
2
apps/list-view-demo/package.json
Normal file
2
apps/list-view-demo/package.json
Normal file
@@ -0,0 +1,2 @@
|
||||
{ "name" : "list-view-demo",
|
||||
"main" : "app.js" }
|
||||
@@ -684,3 +684,43 @@ function performNativeItemTap(listView: listViewModule.ListView, index: number):
|
||||
throw new Error("Cannot perform native item tap");
|
||||
}
|
||||
}
|
||||
|
||||
//export function test_LoadedUnloaded() {
|
||||
// var listView = new listViewModule.ListView();
|
||||
// var vm = {
|
||||
// loadedCount: 0,
|
||||
// unloadedCount: 0,
|
||||
// onViewLoaded: function onViewLoaded(args) {
|
||||
// this.loadedCount++;
|
||||
// console.log(args.object._domId + " LOADED");
|
||||
// },
|
||||
// onViewUnloaded: function onViewUnloaded(args) {
|
||||
// this.unloadedCount++;
|
||||
// console.log(args.object._domId + " UNLOADED");
|
||||
// }
|
||||
// };
|
||||
// listView.itemTemplate = "<Label text=\"{{ $value }}\" loaded=\"{{ onViewLoaded }}\" unloaded=\"{{ onViewUnloaded }}\"/>";
|
||||
// listView.bindingContext = vm;
|
||||
|
||||
// var count = 10;
|
||||
// var modifier = listView.ios ? 1 : 0; // iOS has one fake measure cell that raises loaded.
|
||||
// var generate = function (count: number): observableArray.ObservableArray<string> {
|
||||
// var items = new observableArray.ObservableArray<string>();
|
||||
// for (var i = 0; i < count; i++) {
|
||||
// items.push("Item " + i);
|
||||
// }
|
||||
// return items;
|
||||
// }
|
||||
|
||||
// function testAction(views: Array<viewModule.View>) {
|
||||
// listView.items = generate(count);
|
||||
// TKUnit.wait(ASYNC);
|
||||
// frame.topmost().navigate("pages/navigation/pageB");
|
||||
// TKUnit.wait(ASYNC);
|
||||
// frame.topmost().goBack();
|
||||
// TKUnit.assertEqual(vm.loadedCount, count + modifier, "Loaded Count");
|
||||
// TKUnit.assertEqual(vm.unloadedCount, count, "Unloaded Count");
|
||||
// }
|
||||
|
||||
// helper.buildUIAndRunTest(listView, testAction);
|
||||
//}
|
||||
|
||||
@@ -36,6 +36,7 @@ export class ListView extends common.ListView {
|
||||
private _android: android.widget.ListView;
|
||||
public _realizedItems = {};
|
||||
private _androidViewId: number;
|
||||
public _attachStateChangeListener: android.view.View.OnAttachStateChangeListener;
|
||||
|
||||
public _createUI() {
|
||||
this._android = new android.widget.ListView(this._context);
|
||||
@@ -90,6 +91,28 @@ export class ListView extends common.ListView {
|
||||
}
|
||||
}
|
||||
}));
|
||||
|
||||
this._attachStateChangeListener = new android.view.View.OnAttachStateChangeListener({
|
||||
get owner() {
|
||||
return that.get();
|
||||
},
|
||||
|
||||
onViewAttachedToWindow: function (view: android.view.View) {
|
||||
//
|
||||
},
|
||||
onViewDetachedFromWindow: function (androidView: android.view.View) {
|
||||
var owner = that.get();
|
||||
if (!owner) {
|
||||
return;
|
||||
}
|
||||
|
||||
var view: viewModule.View = this.owner._realizedItems[androidView.hashCode()];
|
||||
if (!view) {
|
||||
return;
|
||||
}
|
||||
view.onUnloaded();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
get android(): android.widget.ListView {
|
||||
@@ -213,6 +236,10 @@ class ListViewAdapter extends android.widget.BaseAdapter {
|
||||
}
|
||||
}
|
||||
|
||||
if (!this._listView._realizedItems[convertView.hashCode()]) {
|
||||
convertView.addOnAttachStateChangeListener(this._listView._attachStateChangeListener);
|
||||
}
|
||||
|
||||
this._listView._realizedItems[convertView.hashCode()] = args.view;
|
||||
// cache the realized index (used to raise the ItemLoading event upon scroll stop)
|
||||
args.view[REALIZED_INDEX] = index;
|
||||
@@ -223,3 +250,4 @@ class ListViewAdapter extends android.widget.BaseAdapter {
|
||||
return convertView;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -23,6 +23,14 @@ class ListViewCell extends UITableViewCell {
|
||||
static new(): ListViewCell {
|
||||
return <ListViewCell>super.new();
|
||||
}
|
||||
|
||||
public removeFromSuperview(): void {
|
||||
super.removeFromSuperview();
|
||||
var view: view.View = (<any>this).view;
|
||||
if (view) {
|
||||
view.onUnloaded();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function notifyForItemAtIndex(listView: definition.ListView, cell: any, eventName: string, indexPath: NSIndexPath) {
|
||||
|
||||
Reference in New Issue
Block a user