@@ -103,7 +103,7 @@ function initializeNativeClasses() {
103
103
104
104
// Get view as bitmap and set it as background. This is workaround for the disapearing nested fragments.
105
105
// 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 ) {
107
107
this . backgroundBitmap = this . loadBitmapFromView ( this . owner . nativeViewProtected ) ;
108
108
}
109
109
@@ -200,18 +200,18 @@ function initializeNativeClasses() {
200
200
}
201
201
202
202
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 ;
203
204
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 ( ) ;
206
207
}
207
208
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);
211
211
// if (index !== -1) {
212
212
// this.owner.fragments.splice(index, 1);
213
213
// }
214
- this . mCurTransaction . detach ( fragment ) ;
214
+ this . mCurTransaction ? .detach ( fragment ) ;
215
215
216
216
if ( this . mCurrentPrimaryItem === fragment ) {
217
217
this . mCurrentPrimaryItem = null ;
@@ -479,7 +479,7 @@ export class Tabs extends TabsBase {
479
479
return nativeView ;
480
480
}
481
481
onSelectedIndexChanged ( oldIndex : number , newIndex : number ) {
482
- const tabBarImplementation = ( this . _tabsBar as unknown ) as PositionChanger ;
482
+ const tabBarImplementation = this . _tabsBar as unknown as PositionChanger ;
483
483
if ( tabBarImplementation ) {
484
484
tabBarImplementation . onSelectedPositionChange ( oldIndex , newIndex ) ;
485
485
}
@@ -621,14 +621,26 @@ export class Tabs extends TabsBase {
621
621
}
622
622
623
623
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 ) ;
626
637
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 ( ) ;
630
642
}
631
- transaction . commitNowAllowingStateLoss ( ) ;
643
+ transactionMap . clear ( ) ; // let's avoid memory leaks
632
644
this . fragments = [ ] ;
633
645
}
634
646
0 commit comments