Skip to content

Commit 98a9680

Browse files
author
Nedyalko Nikolov
committed
Fixed crash when ListView is used in a modal dialog (Android).
1 parent 743a2ef commit 98a9680

File tree

2 files changed

+42
-6
lines changed

2 files changed

+42
-6
lines changed

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

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -558,6 +558,38 @@ export class ListViewTest extends testModule.UITest<listViewModule.ListView> {
558558
}
559559
}
560560

561+
public test_RemovingChildViewsBeforeListView() {
562+
var listView = this.testView;
563+
var converterCalledCounter = 0;
564+
565+
var testConverter = function (value) {
566+
converterCalledCounter++;
567+
return value;
568+
}
569+
570+
app.resources["testConverter"] = testConverter;
571+
572+
var listViewModel = new observable.Observable();
573+
listViewModel.set("items", [1, 2, 3]);
574+
listView.bindingContext = listViewModel;
575+
576+
listView.bind({ sourceProperty: "items", targetProperty: "items" });
577+
listView.itemTemplate = "<StackLayout><Label id=\"testLabel\" text=\"{{ $value, $value | testConverter }}\" /></StackLayout>";
578+
579+
this.waitUntilListViewReady();
580+
581+
if (platform.isAndroid) {
582+
// simulates Angular way of removing views
583+
(<any>listView)._realizedItems.forEach((view, nativeView, map) => {
584+
console.log("view: " + view);
585+
listView._removeView(view);
586+
});
587+
this.tearDown();
588+
// should not crash
589+
TKUnit.assertTrue(true);
590+
}
591+
}
592+
561593
public test_no_memory_leak_when_items_is_regular_array() {
562594
let weakRef = new WeakRef<listViewModule.ListView>(this.testView);
563595
weakRef.get().items = FEW_ITEMS;

tns-core-modules/ui/list-view/list-view.android.ts

Lines changed: 10 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -108,7 +108,10 @@ export class ListView extends common.ListView {
108108
callback(view);
109109
}
110110
else {
111-
callback(view.parent);
111+
// in some cases (like item is unloaded from another place (like angular) view.parent becomes undefined)
112+
if (view.parent) {
113+
callback(view.parent);
114+
}
112115
}
113116
});
114117
}
@@ -124,12 +127,13 @@ export class ListView extends common.ListView {
124127
private clearRealizedCells(): void {
125128
// clear the cache
126129
this._realizedItems.forEach((view, nativeView, map) => {
127-
// This is to clear the StackLayout that is used to wrap non LayoutBase & ProxyViewContainer instances.
128-
if (!(view.parent instanceof ListView)) {
129-
this._removeView(view.parent);
130+
if (view.parent) {
131+
// This is to clear the StackLayout that is used to wrap non LayoutBase & ProxyViewContainer instances.
132+
if (!(view.parent instanceof ListView)) {
133+
this._removeView(view.parent);
134+
}
135+
view.parent._removeView(view);
130136
}
131-
132-
view.parent._removeView(view);
133137
});
134138

135139
this._realizedItems.clear();

0 commit comments

Comments
 (0)