10000 fix(android): nested frames were sometimes not recreated (#9725) · NativeScript/NativeScript@902a4c6 · GitHub
[go: up one dir, main page]

Skip to content

Commit 902a4c6

Browse files
edusperoniNathanWalker
authored andcommitted
fix(android): nested frames were sometimes not recreated (#9725)
BREAKING CHANGE: AndroidFragmentCallbacks now requires onResume as well Migration steps: specify onResume on custom fragment implementations
1 parent 6383882 commit 902a4c6

File tree

4 files changed

+38
-0
lines changed

4 files changed

+38
-0
lines changed

packages/core/ui/frame/fragment.android.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,10 @@ const FragmentClass = (<any>org.nativescript.widgets.FragmentBase).extend('com.t
1919
this._callbacks.onPause(this, superProto.onPause);
2020
},
2121

22+
onResume(): void {
23+
this._callbacks.onResume(this, superProto.onResume);
24+
},
25+
2226
onCreate(savedInstanceState: android.os.Bundle) {
2327
if (!this._callbacks) {
2428
setFragmentCallbacks(this);

packages/core/ui/frame/fragment.transitions.android.ts

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,7 @@ export interface ExpandedEntry extends BackstackEntry {
5151
frameId: number;
5252

5353
isNestedDefaultTransition: boolean;
54+
isAnimationRunning: boolean;
5455
}
5556

5657
export function _setAndroidFragmentTransitions(animated: boolean, navigationTransition: NavigationTransition, currentEntry: ExpandedEntry, newEntry: ExpandedEntry, frameId: number, fragmentTransaction: androidx.fragment.app.FragmentTransaction, isNestedDefaultTransition?: boolean): void {
@@ -60,6 +61,7 @@ export function _setAndroidFragmentTransitions(animated: boolean, navigationTran
6061
if (entries && entries.size > 0) {
6162
throw new Error('Calling navigation before previous navigation finish.');
6263
}
64+
newEntry.isAnimationRunning = false;
6365

6466
allowTransitionOverlap(currentFragment);
6567
allowTransitionOverlap(newFragment);
@@ -227,6 +229,7 @@ function getAnimationListener(): android.animation.Animator.AnimatorListener {
227229
if (Trace.isEnabled()) {
228230
Trace.write(`START ${animator.transitionType} for ${entry.fragmentTag}`, Trace.categories.Transition);
229231
}
232+
entry.isAnimationRunning = true;
230233
}
231234

232235
onAnimationRepeat(animator: ExpandedAnimator): void {
@@ -239,13 +242,15 @@ function getAnimationListener(): android.animation.Animator.AnimatorListener {
239242
if (Trace.isEnabled()) {
240243
Trace.write(`END ${animator.transitionType} for ${animator.entry.fragmentTag}`, Trace.categories.Transition);
241244
}
245+
animator.entry.isAnimationRunning = false;
242246
transitionOrAnimationCompleted(animator.entry, animator.backEntry);
243247
}
244248

245249
onAnimationCancel(animator: ExpandedAnimator): void {
246250
if (Trace.isEnabled()) {
247251
Trace.write(`CANCEL ${animator.transitionType} for ${animator.entry.fragmentTag}`, Trace.categories.Transition);
248252
}
253+
animator.entry.isAnimationRunning = false;
249254
}
250255
}
251256

packages/core/ui/frame/index.android.ts

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -237,6 +237,21 @@ export class Frame extends FrameBase {
237237
this.backgroundColor = this._originalBackground;
238238
this._originalBackground = null;
239239
}
240+
setTimeout(() => {
241+
// there's a bug with nested frames where sometimes the nested fragment is not recreated at all
242+
// so we manually check on loaded event if the fragment is not recreated and recreate it
243+
const currentEntry = this._currentEntry || this._executingContext?.entry;
244+
if (currentEntry) {
245+
if (!currentEntry.fragment) {
246+
const manager = this._getFragmentManager();
247+
const transaction = manager.beginTransaction();
248+
currentEntry.fragment = this.createFragment(currentEntry, currentEntry.fragmentTag);
249+
_updateTransitions(currentEntry);
250+
transaction.replace(this.containerViewId, currentEntry.fragment, currentEntry.fragmentTag);
251+
transaction.commitAllowingStateLoss();
252+
}
253+
}
254+
}, 0);
240255

241256
super.onLoaded();
242257
}
@@ -1002,6 +1017,19 @@ class FragmentCallbacksImplementation implements AndroidFragmentCallbacks {
10021017
}
10031018
}
10041019

1020+
@profile
1021+
public onResume(fragment: org.nativescript.widgets.FragmentBase, superFunc: Function): void {
1022+
const frame = this.entry.resolvedPage.frame;
1023+
// on some cases during the first navigation on nested frames the animation doesn't trigger
1024+
// we depend on the animation (even None animation) to set the entry as the current entry
1025+
// animation should start between start and resume, so if we have an executing navigation here it probably means the animation was skipped
1026+
// so we manually set the entry
1027+
if (frame._executingContext && !(<any>this.entry).isAnimationRunning) {
1028+
frame.setCurrent(this.entry, frame._executingContext.navigationType);
1029+
}
1030+
superFunc.call(fragment);
1031+
}
1032+
10051033
@profile
10061034
public onStop(fragment: androidx.fragment.app.Fragment, superFunc: Function): void {
10071035
superFunc.call(fragment);

packages/core/ui/frame/index.d.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -476,6 +476,7 @@ export interface AndroidFragmentCallbacks {
476476
onDestroyView(fragment: any, superFunc: Function): void;
477477
onDestroy(fragment: any, superFunc: Function): void;
478478
onPause(fragment: any, superFunc: Function): void;
479+
onResume(fragment: any, superFunc: Function): void;
479480
onStop(fragment: any, superFunc: Function): void;
480481
toStringOverride(fragment: any, superFunc: Function): string;
481482
}

0 commit comments

Comments
 (0)
0