Merge branch 'feature/android_fragment_transition' of github.com:Akylas/NativeScript

This commit is contained in:
Martin Guillon
2020-08-27 09:46:26 +02:00
4 changed files with 46 additions and 15 deletions

View File

@ -181,7 +181,7 @@ function _test_PageNavigation_EventSequence(withTransition: boolean) {
helper.navigateWithEntry(navigationEntry); helper.navigateWithEntry(navigationEntry);
helper.goBack(); helper.goBack();
const expectedEventSequence = ['navigatingTo', 'loaded', 'navigatedTo', 'navigatingFrom', 'unloaded', 'navigatedFrom']; const expectedEventSequence = ['navigatingTo', 'loaded', 'navigatedTo', 'navigatingFrom', 'navigatedFrom', 'unloaded'];
TKUnit.arrayAssert(eventSequence, expectedEventSequence, 'Actual event sequence is not equal to expected. Actual: ' + eventSequence + '; Expected: ' + expectedEventSequence); TKUnit.arrayAssert(eventSequence, expectedEventSequence, 'Actual event sequence is not equal to expected. Actual: ' + eventSequence + '; Expected: ' + expectedEventSequence);
} }

View File

@ -26,6 +26,7 @@ let AnimationListener: android.animation.Animator.AnimatorListener;
interface ExpandedTransitionListener extends androidx.transition.Transition.TransitionListener { interface ExpandedTransitionListener extends androidx.transition.Transition.TransitionListener {
entry: ExpandedEntry; entry: ExpandedEntry;
backEntry?: BackstackEntry;
transition: androidx.transition.Transition; transition: androidx.transition.Transition;
} }
@ -149,7 +150,6 @@ export function _setAndroidFragmentTransitions(animated: boolean, navigationTran
setupCurrentFragmentExplodeTransition(navigationTransition, currentEntry); setupCurrentFragmentExplodeTransition(navigationTransition, currentEntry);
} }
} else if (name.indexOf('flip') === 0) { } else if (name.indexOf('flip') === 0) {
navigationTransition = { duration: 3000, curve: null };
const direction = name.substr('flip'.length) || 'right'; //Extract the direction from the string const direction = name.substr('flip'.length) || 'right'; //Extract the direction from the string
const flipTransition = new FlipTransition(direction, navigationTransition.duration, navigationTransition.curve); const flipTransition = new FlipTransition(direction, navigationTransition.duration, navigationTransition.curve);
@ -224,6 +224,7 @@ function getAnimationListener(): android.animation.Animator.AnimatorListener {
onAnimationStart(animator: ExpandedAnimator): void { onAnimationStart(animator: ExpandedAnimator): void {
const entry = animator.entry; const entry = animator.entry;
const backEntry = animator.backEntry;
addToWaitingQueue(entry); addToWaitingQueue(entry);
if (Trace.isEnabled()) { if (Trace.isEnabled()) {
Trace.write(`START ${animator.transitionType} for ${entry.fragmentTag}`, Trace.categories.Transition); Trace.write(`START ${animator.transitionType} for ${entry.fragmentTag}`, Trace.categories.Transition);
@ -237,10 +238,13 @@ function getAnimationListener(): android.animation.Animator.AnimatorListener {
} }
onAnimationEnd(animator: ExpandedAnimator): void { onAnimationEnd(animator: ExpandedAnimator): void {
const entry = animator.entry;
const backEntry = animator.backEntry;
if (Trace.isEnabled()) { if (Trace.isEnabled()) {
Trace.write(`END ${animator.transitionType} for ${animator.entry.fragmentTag}`, Trace.categories.Transition); Trace.write(`END ${animator.transitionType} for ${entry.fragmentTag} backEntry:${backEntry ? backEntry.fragmentTag : 'none'}`, Trace.categories.Transition);
} }
transitionOrAnimationCompleted(animator.entry, animator.backEntry); transitionOrAnimationCompleted(entry, backEntry);
animator.backEntry = null;
} }
onAnimationCancel(animator: ExpandedAnimator): void { onAnimationCancel(animator: ExpandedAnimator): void {
@ -346,10 +350,12 @@ function getTransitionListener(entry: ExpandedEntry, transition: androidx.transi
onTransitionEnd(transition: androidx.transition.Transition): void { onTransitionEnd(transition: androidx.transition.Transition): void {
const entry = this.entry; const entry = this.entry;
const backEntry = this.backEntry;
if (Trace.isEnabled()) { if (Trace.isEnabled()) {
Trace.write(`END ${toShortString(transition)} transition for ${entry.fragmentTag}`, Trace.categories.Transition); Trace.write(`END ${toShortString(transition)} transition for ${entry.fragmentTag} backEntry:${backEntry ? backEntry.fragmentTag : 'none'}`, Trace.categories.Transition);
} }
transitionOrAnimationCompleted(entry, this.backEntry); transitionOrAnimationCompleted(entry, backEntry);
this.backEntry = null;
} }
onTransitionResume(transition: androidx.transition.Transition): void { onTransitionResume(transition: androidx.transition.Transition): void {
@ -661,6 +667,7 @@ function transitionOrAnimationCompleted(entry: ExpandedEntry, backEntry: Backsta
if (!entries) { if (!entries) {
return; return;
} }
console.log('transitionOrAnimationCompleted', frameId, backEntry && backEntry.fragmentTag, waitingQueue.size, entries.size, completedEntries.size );
entries.delete(entry); entries.delete(entry);
if (entries.size === 0) { if (entries.size === 0) {

View File

@ -259,8 +259,8 @@ export class FrameBase extends CustomLayoutView {
public _updateBackstack(entry: BackstackEntry, navigationType: NavigationType): void { public _updateBackstack(entry: BackstackEntry, navigationType: NavigationType): void {
const isBack = navigationType === NavigationType.back; const isBack = navigationType === NavigationType.back;
const isReplace = navigationType === NavigationType.replace; const isReplace = navigationType === NavigationType.replace;
this.raiseCurrentPageNavigatedEvents(isBack);
const current = this._currentEntry; const current = this._currentEntry;
this.raiseCurrentPageNavigatedEvents(isBack);
// Do nothing for Hot Module Replacement // Do nothing for Hot Module Replacement
if (isBack) { if (isBack) {
@ -296,10 +296,6 @@ export class FrameBase extends CustomLayoutView {
private raiseCurrentPageNavigatedEvents(isBack: boolean) { private raiseCurrentPageNavigatedEvents(isBack: boolean) {
const page = this.currentPage; const page = this.currentPage;
if (page) { if (page) {
if (page.isLoaded) {
// Forward navigation does not remove page from frame so we raise unloaded manually.
page.callUnloaded();
}
page.onNavigatedFrom(isBack); page.onNavigatedFrom(isBack);
} }
} }

View File

@ -19,6 +19,7 @@ import { Builder } from '../builder';
import { CSSUtils } from '../../css/system-classes'; import { CSSUtils } from '../../css/system-classes';
import { Device } from '../../platform'; import { Device } from '../../platform';
import { profile } from '../../profiling'; import { profile } from '../../profiling';
import { ExpandedEntry } from './fragment.transitions.android';
export * from './frame-common'; export * from './frame-common';
@ -319,6 +320,8 @@ export class Frame extends FrameBase {
// If we had real navigation process queue. // If we had real navigation process queue.
this._processNavigationQueue(entry.resolvedPage); this._processNavigationQueue(entry.resolvedPage);
} else { } else {
// Otherwise currentPage was recreated so this wasn't real navigation. // Otherwise currentPage was recreated so this wasn't real navigation.
// Continue with next item in the queue. // Continue with next item in the queue.
@ -431,7 +434,14 @@ export class Frame extends FrameBase {
//transaction.setTransition(androidx.fragment.app.FragmentTransaction.TRANSIT_FRAGMENT_OPEN); //transaction.setTransition(androidx.fragment.app.FragmentTransaction.TRANSIT_FRAGMENT_OPEN);
} }
if (clearHistory || isReplace) {
transaction.replace(this.containerViewId, newFragment, newFragmentTag); transaction.replace(this.containerViewId, newFragment, newFragmentTag);
} else {
transaction.add(this.containerViewId, newFragment, newFragmentTag);
}
if (this._currentEntry && this._currentEntry.entry.backstackVisible === false) {
transaction.remove(this._currentEntry.fragment);
}
transaction.commitAllowingStateLoss(); transaction.commitAllowingStateLoss();
} }
@ -453,7 +463,25 @@ export class Frame extends FrameBase {
_reverseTransitions(backstackEntry, this._currentEntry); _reverseTransitions(backstackEntry, this._currentEntry);
transaction.replace(this.containerViewId, backstackEntry.fragment, backstackEntry.fragmentTag); const currentIndex =this.backStack.length;
const goBackToIndex = this.backStack.indexOf(backstackEntry);
// the order is important so that the transition listener called be
// the one from the current entry we are going back from
if (this._currentEntry !== backstackEntry) {
const entry = this._currentEntry as ExpandedEntry;
// if we are going back we need to store where we are backing to
// so that we can set the current entry
// it only needs to be done on the return transition
if (entry.returnTransitionListener) {
entry.returnTransitionListener.backEntry = backstackEntry;
}
transaction.remove((this._currentEntry).fragment);
}
for (let index = goBackToIndex + 1; index < currentIndex; index++) {
transaction.remove(this.backStack[index].fragment);
}
transaction.commitAllowingStateLoss(); transaction.commitAllowingStateLoss();
} }