From 96355da7c53d207ce36e947407bf7c9845fde18e Mon Sep 17 00:00:00 2001 From: Manol Donev Date: Tue, 20 Nov 2018 19:17:15 +0200 Subject: [PATCH] fix(android-fragment): child already has a parent --- tns-core-modules/ui/frame/frame.android.ts | 36 +++++++++++----------- 1 file changed, 18 insertions(+), 18 deletions(-) diff --git a/tns-core-modules/ui/frame/frame.android.ts b/tns-core-modules/ui/frame/frame.android.ts index 81d6cf7fca..417d817bb2 100644 --- a/tns-core-modules/ui/frame/frame.android.ts +++ b/tns-core-modules/ui/frame/frame.android.ts @@ -834,6 +834,24 @@ class FragmentCallbacksImplementation implements AndroidFragmentCallbacks { entry.viewSavedState = null; } + // fixes 'java.lang.IllegalStateException: The specified child already has a parent. You must call removeView() on the child's parent first'. + // on app resume in nested frame scenarios with support library version greater than 26.0.0 + // HACK: this whole code block shouldn't be necessary as the native view is supposedly removed from its parent + // right after onDestroyView(...) is called but for some reason the fragment view (page) still thinks it has a + // parent while its supposed parent believes it properly removed its children; in order to "force" the child to + // lose its parent we temporarily add it to the parent, and then remove it (addViewInLayout doesn't trigger layout pass) + const nativeView = page.nativeViewProtected; + if (nativeView != null) { + const parentView = nativeView.getParent(); + if (parentView instanceof android.view.ViewGroup) { + if (parentView.getChildCount() === 0) { + parentView.addViewInLayout(nativeView, -1, new org.nativescript.widgets.CommonLayoutParams()); + } + + parentView.removeView(nativeView); + } + } + return page.nativeViewProtected; } @@ -873,24 +891,6 @@ class FragmentCallbacksImplementation implements AndroidFragmentCallbacks { traceError(`${fragment}.onDestroy: entry has no resolvedPage`); return null; } - - // fixes 'java.lang.IllegalStateException: The specified child already has a parent. You must call removeView() on the child's parent first'. - // on app resume in nested frame scenarios with support library version greater than 26.0.0 - // HACK: this whole code block shouldn't be necessary as the native view is supposedly removed from its parent - // right after onDestroyView(...) is called but for some reason the fragment view (page) still thinks it has a - // parent while its supposed parent believes it properly removed its children; in order to "force" the child to - // lose its parent we temporarily add it to the parent, and then remove it (addViewInLayout doesn't trigger layout pass) - const nativeView = page.nativeViewProtected; - if (nativeView != null) { - const parentView = nativeView.getParent(); - if (parentView instanceof android.view.ViewGroup) { - if (parentView.getChildCount() === 0) { - parentView.addViewInLayout(nativeView, -1, new org.nativescript.widgets.CommonLayoutParams()); - } - - parentView.removeView(nativeView); - } - } } @profile