@@ -103,7 +103,7 @@ function initializeNativeClasses() {
103103
104104 // Get view as bitmap and set it as background. This is workaround for the disapearing nested fragments.
105105 // TODO: Consider removing it when update to androidx.fragment:1.2.0
106- if ( hasRemovingParent && this . owner . selectedIndex === this . index ) {
106+ if ( hasRemovingParent && this . owner . selectedIndex === this . index && this . owner . nativeViewProtected ) {
107107 this . backgroundBitmap = this . loadBitmapFromView ( this . owner . nativeViewProtected ) ;
108108 }
109109
@@ -200,18 +200,18 @@ function initializeNativeClasses() {
200200 }
201201
202202 destroyItem ( container : android . view . ViewGroup , position : number , object : java . lang . Object ) : void {
203+ const fragment : androidx . fragment . app . Fragment = object as androidx . fragment . app . Fragment ;
203204 if ( ! this . mCurTransaction ) {
204- const fragmentManager = this . owner . _getFragmentManager ( ) ;
205- this . mCurTransaction = fragmentManager . beginTransaction ( ) ;
205+ const fragmentManager : androidx . fragment . app . FragmentManager = this . owner . _getParentFragmentManagerFromFragment ( fragment ) ;
206+ this . mCurTransaction = fragmentManager ? .beginTransaction ( ) ;
206207 }
207208
208- const fragment : androidx . fragment . app . Fragment = object as androidx . fragment . app . Fragment ;
209-
210- const index = this . owner . fragments . indexOf ( fragment ) ;
209+ // detached fragments are still attached to the fragment manager
210+ // const index = this.owner.fragments.indexOf(fragment);
211211 // if (index !== -1) {
212212 // this.owner.fragments.splice(index, 1);
213213 // }
214- this . mCurTransaction . detach ( fragment ) ;
214+ this . mCurTransaction ? .detach ( fragment ) ;
215215
216216 if ( this . mCurrentPrimaryItem === fragment ) {
217217 this . mCurrentPrimaryItem = null ;
@@ -479,7 +479,7 @@ export class Tabs extends TabsBase {
479479 return nativeView ;
480480 }
481481 onSelectedIndexChanged ( oldIndex : number , newIndex : number ) {
482- const tabBarImplementation = ( this . _tabsBar as unknown ) as PositionChanger ;
482+ const tabBarImplementation = this . _tabsBar as unknown as PositionChanger ;
483483 if ( tabBarImplementation ) {
484484 tabBarImplementation . onSelectedPositionChange ( oldIndex , newIndex ) ;
485485 }
@@ -621,14 +621,26 @@ export class Tabs extends TabsBase {
621621 }
622622
623623 private disposeCurrentFragments ( ) : void {
624- const fragmentManager = this . _getFragmentManager ( ) ;
625- const transaction = fragmentManager . beginTransaction ( ) ;
624+ // we need to use this because the destroyItem only detaches the item
625+ // here we clean up all fragments, even ones that were detached to another manager, which may happen on suspend/resume
626+ // alternative: actually remove the fragment on destroyItem
627+ const transactionMap = new Map < androidx . fragment . app . FragmentManager , androidx . fragment . app . FragmentTransaction > ( ) ;
628+ for ( const fragment of this . fragments ) {
629+ const fragmentManager = this . _getParentFragmentManagerFromFragment ( fragment ) ;
630+ if ( ! fragmentManager || fragmentManager . isDestroyed ( ) ) {
631+ continue ;
632+ }
633+ if ( ! transactionMap . has ( fragmentManager ) ) {
634+ transactionMap . set ( fragmentManager , fragmentManager . beginTransaction ( ) ) ;
635+ }
636+ const transaction = transactionMap . get ( fragmentManager ) ;
626637
627- const fragments = this . fragments ;
628- for ( let i = 0 ; i < fragments . length ; i ++ ) {
629- transaction . remove ( fragments [ i ] ) ;
638+ transaction . remove ( fragment ) ;
639+ }
640+ for ( const transaction of transactionMap . values ( ) ) {
641+ transaction . commitNowAllowingStateLoss ( ) ;
630642 }
631- transaction . commitNowAllowingStateLoss ( ) ;
643+ transactionMap . clear ( ) ; // let's avoid memory leaks
632644 this . fragments = [ ] ;
633645 }
634646
0 commit comments