Disable view recycling

This commit is contained in:
vakrilov
2017-08-01 16:28:58 +03:00
parent 7983895c8e
commit 7c8aa12d8c
4 changed files with 104 additions and 94 deletions

View File

@@ -241,59 +241,61 @@ let cssSetters: Map<string, any>;
let defaultNativeGetters: Map<string, (view) => any>; let defaultNativeGetters: Map<string, (view) => any>;
export function nativeView_recycling_test(createNew: () => View, createLayout?: () => LayoutBase, nativeGetters?: Map<string, (view) => any>, customSetters?: Map<string, any>) { export function nativeView_recycling_test(createNew: () => View, createLayout?: () => LayoutBase, nativeGetters?: Map<string, (view) => any>, customSetters?: Map<string, any>) {
if (isIOS) { return;
// recycling not implemented yet.
return;
}
setupSetters(); // if (isIOS) {
const page = getClearCurrentPage(); // // recycling not implemented yet.
let layout: LayoutBase = new FlexboxLayout(); // return;
if (createLayout) { // }
// This is done on purpose. We need the constructor of Flexbox
// to run otherwise some module fileds stays uninitialized.
layout = createLayout();
}
page.content = layout; // setupSetters();
// const page = getClearCurrentPage();
// let layout: LayoutBase = new FlexboxLayout();
// if (createLayout) {
// // This is done on purpose. We need the constructor of Flexbox
// // to run otherwise some module fileds stays uninitialized.
// layout = createLayout();
// }
const first = createNew(); // page.content = layout;
const test = createNew();
// Make sure we are not reusing a native views. // const first = createNew();
first.recycleNativeView = false; // const test = createNew();
test.recycleNativeView = false;
page.content = layout; // // Make sure we are not reusing a native views.
// first.recycleNativeView = false;
// test.recycleNativeView = false;
layout.addChild(test); // page.content = layout;
setValue(test.style, cssSetters); // layout.addChild(test);
setValue(test, setters, customSetters);
// Needed so we can reset formattedText
test["secure"] = false;
const nativeView = test.nativeView; // setValue(test.style, cssSetters);
// Mark so we reuse the native views. // setValue(test, setters, customSetters);
test.recycleNativeView = true; // // Needed so we can reset formattedText
layout.removeChild(test); // test["secure"] = false;
const newer = createNew();
newer.recycleNativeView = true;
layout.addChild(newer);
layout.addChild(first);
if (first.typeName !== "SearchBar" && sdkVersion > 19) { // const nativeView = test.nativeView;
// There are way too many differences in native methods for search-bar. // // Mark so we reuse the native views.
// There are too many methods that just throw for newly created views in API lvl 19 and 17 // test.recycleNativeView = true;
compareUsingReflection(newer, first); // layout.removeChild(test);
} // const newer = createNew();
// newer.recycleNativeView = true;
// layout.addChild(newer);
// layout.addChild(first);
TKUnit.assertEqual(newer.nativeView, nativeView, "nativeView not reused."); // if (first.typeName !== "SearchBar" && sdkVersion > 19) {
checkDefaults(newer, first, props, nativeGetters || defaultNativeGetters); // // There are way too many differences in native methods for search-bar.
checkDefaults(newer, first, styleProps, nativeGetters || defaultNativeGetters); // // There are too many methods that just throw for newly created views in API lvl 19 and 17
// compareUsingReflection(newer, first);
// }
layout.removeChild(newer); // TKUnit.assertEqual(newer.nativeView, nativeView, "nativeView not reused.");
layout.removeChild(first); // checkDefaults(newer, first, props, nativeGetters || defaultNativeGetters);
// checkDefaults(newer, first, styleProps, nativeGetters || defaultNativeGetters);
// layout.removeChild(newer);
// layout.removeChild(first);
} }
function compareUsingReflection(recycledNativeView: View, newNativeView: View): void { function compareUsingReflection(recycledNativeView: View, newNativeView: View): void {

View File

@@ -575,36 +575,37 @@ export function test_NativeSetter_called_when_add_and_remove() {
}); });
}; };
export function test_NativeSetter_called_when_add_and_remove_and_recycled() { // Disable view recycling
const firstView = new TestView("firstView"); // export function test_NativeSetter_called_when_add_and_remove_and_recycled() {
const secondView = new TestView("secondView"); // const firstView = new TestView("firstView");
secondView.recycleNativeView = !isIOS; // const secondView = new TestView("secondView");
secondView.customCssProperty = "testCssValue"; // secondView.recycleNativeView = !isIOS;
secondView.custom = "testViewValue"; // secondView.customCssProperty = "testCssValue";
// secondView.custom = "testViewValue";
helper.buildUIAndRunTest(firstView, () => { // helper.buildUIAndRunTest(firstView, () => {
TKUnit.assertEqual(secondView.cssPropCounter, 0, "1"); // TKUnit.assertEqual(secondView.cssPropCounter, 0, "1");
TKUnit.assertEqual(secondView.viewPropCounter, 0, "2"); // TKUnit.assertEqual(secondView.viewPropCounter, 0, "2");
// Add to visual tree // // Add to visual tree
firstView.addChild(secondView); // firstView.addChild(secondView);
TKUnit.assertEqual(secondView.cssPropCounter, 1, "3"); // TKUnit.assertEqual(secondView.cssPropCounter, 1, "3");
TKUnit.assertEqual(secondView.viewPropCounter, 1, "4"); // TKUnit.assertEqual(secondView.viewPropCounter, 1, "4");
// Set new value // // Set new value
secondView.customCssProperty = "test2"; // secondView.customCssProperty = "test2";
secondView.custom = "test2"; // secondView.custom = "test2";
TKUnit.assertEqual(secondView.cssPropCounter, 2, "5"); // TKUnit.assertEqual(secondView.cssPropCounter, 2, "5");
TKUnit.assertEqual(secondView.viewPropCounter, 2, "6"); // TKUnit.assertEqual(secondView.viewPropCounter, 2, "6");
// Remove from visual tree // // Remove from visual tree
firstView.removeChild(secondView); // firstView.removeChild(secondView);
// we don't recycle nativeViews on iOS yet so reset is not called. // // we don't recycle nativeViews on iOS yet so reset is not called.
TKUnit.assertEqual(secondView.cssPropCounter, isIOS ? 2 : 3, "7"); // TKUnit.assertEqual(secondView.cssPropCounter, isIOS ? 2 : 3, "7");
TKUnit.assertEqual(secondView.viewPropCounter, isIOS ? 2 : 3, "8"); // TKUnit.assertEqual(secondView.viewPropCounter, isIOS ? 2 : 3, "8");
}); // });
}; // };
export function test_InheritableProperties_getValuesFromParent() { export function test_InheritableProperties_getValuesFromParent() {
const testValue = 35; const testValue = 35;

View File

@@ -146,7 +146,9 @@ export abstract class ViewBase extends Observable {
public nativeView: any; public nativeView: any;
public bindingContext: any; public bindingContext: any;
public recycleNativeView: boolean;
// Reserved for future use. Currently not used
public recycleNativeView: any;
/** /**
* Gets the name of the constructor function for this instance. E.g. for a Button class this will return "Button". * Gets the name of the constructor function for this instance. E.g. for a Button class this will return "Button".

View File

@@ -133,7 +133,8 @@ export abstract class ViewBase extends Observable implements ViewBaseDefinition
public static loadedEvent = "loaded"; public static loadedEvent = "loaded";
public static unloadedEvent = "unloaded"; public static unloadedEvent = "unloaded";
private _recycleNativeView: boolean; // Disable view recycling
// private _recycleNativeView: boolean;
private _iosView: Object; private _iosView: Object;
private _androidView: Object; private _androidView: Object;
private _style: Style; private _style: Style;
@@ -216,12 +217,13 @@ export abstract class ViewBase extends Observable implements ViewBaseDefinition
return types.getClass(this); return types.getClass(this);
} }
get recycleNativeView(): boolean { // Disable view recycling
return this._recycleNativeView; get recycleNativeView(): any {
// return this._recycleNativeView;
return false;
} }
set recycleNativeView(value: any) {
set recycleNativeView(value: boolean) { // this._recycleNativeView = typeof value === "boolean" ? value : booleanConverter(value);
this._recycleNativeView = typeof value === "boolean" ? value : booleanConverter(value);
} }
get style(): Style { get style(): Style {
@@ -670,16 +672,17 @@ export abstract class ViewBase extends Observable implements ViewBaseDefinition
} }
private resetNativeViewInternal(): void { private resetNativeViewInternal(): void {
const nativeView = this.nativeView; // Disable view recycling
if (nativeView && this._recycleNativeView && isAndroid) { // const nativeView = this.nativeView;
resetNativeView(this); // if (nativeView && this._recycleNativeView && isAndroid) {
if (this._isPaddingRelative) { // resetNativeView(this);
nativeView.setPaddingRelative(this._defaultPaddingLeft, this._defaultPaddingTop, this._defaultPaddingRight, this._defaultPaddingBottom); // if (this._isPaddingRelative) {
} else { // nativeView.setPaddingRelative(this._defaultPaddingLeft, this._defaultPaddingTop, this._defaultPaddingRight, this._defaultPaddingBottom);
nativeView.setPadding(this._defaultPaddingLeft, this._defaultPaddingTop, this._defaultPaddingRight, this._defaultPaddingBottom); // } else {
} // nativeView.setPadding(this._defaultPaddingLeft, this._defaultPaddingTop, this._defaultPaddingRight, this._defaultPaddingBottom);
this.resetNativeView(); // }
} // this.resetNativeView();
// }
if (this._cssState) { if (this._cssState) {
this._cancelAllAnimations(); this._cancelAllAnimations();
} }
@@ -702,9 +705,10 @@ export abstract class ViewBase extends Observable implements ViewBaseDefinition
let nativeView; let nativeView;
if (isAndroid) { if (isAndroid) {
if (this._recycleNativeView) { // Disable view recycling
nativeView = <android.view.View>getNativeView(context, this.typeName); // if (this._recycleNativeView) {
} // nativeView = <android.view.View>getNativeView(context, this.typeName);
// }
if (!nativeView) { if (!nativeView) {
nativeView = <android.view.View>this.createNativeView(); nativeView = <android.view.View>this.createNativeView();
@@ -805,13 +809,14 @@ export abstract class ViewBase extends Observable implements ViewBaseDefinition
this.parent._removeViewFromNativeVisualTree(this); this.parent._removeViewFromNativeVisualTree(this);
} }
const nativeView = this.nativeView; // Disable view recycling
if (nativeView && this._recycleNativeView && isAndroid) { // const nativeView = this.nativeView;
const nativeParent = isAndroid ? (<android.view.View>nativeView).getParent() : (<UIView>nativeView).superview; // if (nativeView && this._recycleNativeView && isAndroid) {
if (!nativeParent) { // const nativeParent = isAndroid ? (<android.view.View>nativeView).getParent() : (<UIView>nativeView).superview;
putNativeView(this._context, this); // if (!nativeParent) {
} // putNativeView(this._context, this);
} // }
// }
this.disposeNativeView(); this.disposeNativeView();