@@ -19,7 +19,7 @@ interface TransitionListener {
19
19
new ( entry : ExpandedEntry , transition : android . transition . Transition ) : ExpandedTransitionListener ;
20
20
}
21
21
22
- interface ExpandedAnimation extends android . view . animation . Animation {
22
+ interface ExpandedAnimator extends android . animation . Animator {
23
23
entry : ExpandedEntry ;
24
24
transitionType ?: string ;
25
25
}
@@ -35,27 +35,28 @@ interface ExpandedEntry extends BackstackEntry {
35
35
reenterTransitionListener : ExpandedTransitionListener ;
36
36
returnTransitionListener : ExpandedTransitionListener ;
37
37
38
- enterAnimation : ExpandedAnimation ;
39
- exitAnimation : ExpandedAnimation ;
40
- popEnterAnimation : ExpandedAnimation ;
41
- popExitAnimation : ExpandedAnimation ;
38
+ enterAnimator : ExpandedAnimator ;
39
+ exitAnimator : ExpandedAnimator ;
40
+ popEnterAnimator : ExpandedAnimator ;
41
+ popExitAnimator : ExpandedAnimator ;
42
42
43
- defaultEnterAnimation : ExpandedAnimation ;
44
- defaultExitAnimation : ExpandedAnimation ;
43
+ defaultEnterAnimator : ExpandedAnimator ;
44
+ defaultExitAnimator : ExpandedAnimator ;
45
45
46
46
transition : Transition ;
47
47
transitionName : string ;
48
48
frameId : number
49
49
}
50
50
51
51
const sdkVersion = lazy ( ( ) => parseInt ( device . sdkVersion ) ) ;
52
+ const intEvaluator = lazy ( ( ) => new android . animation . IntEvaluator ( ) ) ;
52
53
const defaultInterpolator = lazy ( ( ) => new android . view . animation . AccelerateDecelerateInterpolator ( ) ) ;
53
54
54
55
export const waitingQueue = new Map < number , Set < ExpandedEntry > > ( ) ;
55
56
export const completedEntries = new Map < number , ExpandedEntry > ( ) ;
56
57
57
58
let TransitionListener : TransitionListener ;
58
- let AnimationListener : android . view . animation . Animation . AnimationListener ;
59
+ let AnimationListener : android . animation . Animator . AnimatorListener ;
59
60
60
61
export function _setAndroidFragmentTransitions (
61
62
animated : boolean ,
@@ -170,39 +171,39 @@ export function _setAndroidFragmentTransitions(
170
171
printTransitions ( newEntry ) ;
171
172
}
172
173
173
- export function _onFragmentCreateAnimation ( entry : ExpandedEntry , fragment : android . support . v4 . app . Fragment , nextAnim : number , enter : boolean ) : android . view . animation . Animation {
174
- let animation : android . view . animation . Animation ;
174
+ export function _onFragmentCreateAnimator ( entry : ExpandedEntry , fragment : android . support . v4 . app . Fragment , nextAnim : number , enter : boolean ) : android . animation . Animator {
175
+ let animator : android . animation . Animator ;
175
176
switch ( nextAnim ) {
176
177
case AnimationType . enterFakeResourceId :
177
- animation = entry . enterAnimation ;
178
+ animator = entry . enterAnimator ;
178
179
break ;
179
180
180
181
case AnimationType . exitFakeResourceId :
181
- animation = entry . exitAnimation ;
182
+ animator = entry . exitAnimator ;
182
183
break ;
183
184
184
185
case AnimationType . popEnterFakeResourceId :
185
- animation = entry . popEnterAnimation ;
186
+ animator = entry . popEnterAnimator ;
186
187
break ;
187
188
188
189
case AnimationType . popExitFakeResourceId :
189
- animation = entry . popExitAnimation ;
190
+ animator = entry . popExitAnimator ;
190
191
break ;
191
192
}
192
193
193
- if ( ! animation && sdkVersion ( ) >= 21 ) {
194
+ if ( ! animator && sdkVersion ( ) >= 21 ) {
194
195
const view = fragment . getView ( ) ;
195
196
const jsParent = entry . resolvedPage . parent ;
196
197
const parent = view . getParent ( ) || ( jsParent && jsParent . nativeViewProtected ) ;
197
198
const animatedEntries = _getAnimatedEntries ( entry . frameId ) ;
198
199
if ( ! animatedEntries || ! animatedEntries . has ( entry ) ) {
199
200
if ( parent && ! ( < any > parent ) . isLaidOut ( ) ) {
200
- animation = enter ? entry . defaultEnterAnimation : entry . defaultExitAnimation ;
201
+ animator = enter ? entry . defaultEnterAnimator : entry . defaultExitAnimator ;
201
202
}
202
203
}
203
204
}
204
205
205
- return animation ;
206
+ return animator ;
206
207
}
207
208
208
209
export function _getAnimatedEntries ( frameId : number ) : Set < BackstackEntry > {
@@ -312,40 +313,40 @@ function getTransitionListener(entry: ExpandedEntry, transition: android.transit
312
313
return new TransitionListener ( entry , transition ) ;
313
314
}
314
315
315
- function getAnimationListener ( ) : android . view . animation . Animation . AnimationListener {
316
+ function getAnimationListener ( ) : android . animation . Animator . AnimatorListener {
316
317
if ( ! AnimationListener ) {
317
- @Interfaces ( [ android . view . animation . Animation . AnimationListener ] )
318
- class AnimationListenerImpl extends java . lang . Object implements android . view . animation . Animation . AnimationListener {
318
+ @Interfaces ( [ android . animation . Animator . AnimatorListener ] )
319
+ class AnimationListenerImpl extends java . lang . Object implements android . animation . Animator . AnimatorListener {
319
320
constructor ( ) {
320
321
super ( ) ;
321
322
return global . __native ( this ) ;
322
323
}
323
324
324
- onAnimationStart ( animation : ExpandedAnimation ) : void {
325
- const entry = animation . entry ;
325
+ onAnimationStart ( animator : ExpandedAnimator ) : void {
326
+ const entry = animator . entry ;
326
327
addToWaitingQueue ( entry ) ;
327
328
if ( traceEnabled ( ) ) {
328
- traceWrite ( `START ${ animation . transitionType } for ${ entry . fragmentTag } ` , traceCategories . Transition ) ;
329
+ traceWrite ( `START ${ animator . transitionType } for ${ entry . fragmentTag } ` , traceCategories . Transition ) ;
329
330
}
330
331
}
331
332
332
- onAnimationRepeat ( animation : ExpandedAnimation ) : void {
333
+ onAnimationRepeat ( animator : ExpandedAnimator ) : void {
333
334
if ( traceEnabled ( ) ) {
334
- traceWrite ( `REPEAT ${ animation . transitionType } for ${ animation . entry . fragmentTag } ` , traceCategories . Transition ) ;
335
+ traceWrite ( `REPEAT ${ animator . transitionType } for ${ animator . entry . fragmentTag } ` , traceCategories . Transition ) ;
335
336
}
336
337
}
337
338
338
- onAnimationEnd ( animation : ExpandedAnimation ) : void {
339
+ onAnimationEnd ( animator : ExpandedAnimator ) : void {
339
340
if ( traceEnabled ( ) ) {
340
- traceWrite ( `END ${ animation . transitionType } for ${ animation . entry . fragmentTag } ` , traceCategories . Transition ) ;
341
+ traceWrite ( `END ${ animator . transitionType } for ${ animator . entry . fragmentTag } ` , traceCategories . Transition ) ;
341
342
}
342
343
343
- transitionOrAnimationCompleted ( animation . entry ) ;
344
+ transitionOrAnimationCompleted ( animator . entry ) ;
344
345
}
345
346
346
- onAnimationCancel ( animation : ExpandedAnimation ) : void {
347
+ onAnimationCancel ( animator : ExpandedAnimator ) : void {
347
348
if ( traceEnabled ( ) ) {
348
- traceWrite ( `CANCEL ${ animation . transitionType } for ${ animation . entry . fragmentTag } ` , traceCategories . Transition ) ;
349
+ traceWrite ( `CANCEL ${ animator . transitionType } for ${ animator . entry . fragmentTag } ` , traceCategories . Transition ) ;
349
350
}
350
351
}
351
352
}
@@ -367,18 +368,19 @@ function addToWaitingQueue(entry: ExpandedEntry): void {
367
368
entries . add ( entry ) ;
368
369
}
369
370
370
- function clearAnimationListener ( animation : ExpandedAnimation ) : void {
371
- if ( ! animation ) {
371
+ function clearAnimationListener ( animator : ExpandedAnimator , listener : android . animation . Animator . AnimatorListener ) : void {
372
+ if ( ! animator ) {
372
373
return ;
373
374
}
374
375
376
+ animator . removeListener ( listener ) ;
377
+
375
378
if ( traceEnabled ( ) ) {
376
- const entry = animation . entry ;
377
- traceWrite ( `Clear ${ animation . transitionType } - ${ entry . transition } for ${ entry . fragmentTag } ` , traceCategories . Transition ) ;
379
+ const entry = animator . entry ;
380
+ traceWrite ( `Clear ${ animator . transitionType } - ${ entry . transition } for ${ entry . fragmentTag } ` , traceCategories . Transition ) ;
378
381
}
379
382
380
- animation . setAnimationListener ( null ) ;
381
- animation . entry = null ;
383
+ animator . entry = null ;
382
384
}
383
385
384
386
function clearExitAndReenterTransitions ( entry : ExpandedEntry , removeListener : boolean ) : void {
@@ -477,10 +479,11 @@ function clearEntry(entry: ExpandedEntry, removeListener: boolean): void {
477
479
}
478
480
479
481
if ( removeListener ) {
480
- clearAnimationListener ( entry . enterAnimation ) ;
481
- clearAnimationListener ( entry . exitAnimation ) ;
482
- clearAnimationListener ( entry . popEnterAnimation ) ;
483
- clearAnimationListener ( entry . popExitAnimation ) ;
482
+ const listener = getAnimationListener ( ) ;
483
+ clearAnimationListener ( entry . enterAnimator , listener ) ;
484
+ clearAnimationListener ( entry . exitAnimator , listener ) ;
485
+ clearAnimationListener ( entry . popEnterAnimator , listener ) ;
486
+ clearAnimationListener ( entry . popExitAnimator , listener ) ;
484
487
}
485
488
}
486
489
@@ -617,21 +620,21 @@ function setupNewFragmentExplodeTransition(navTransition: NavigationTransition,
617
620
function setupExitAndPopEnterAnimation ( entry : ExpandedEntry , transition : Transition ) : void {
618
621
const listener = getAnimationListener ( ) ;
619
622
620
- // remove previous listener if we are changing the animation .
621
- clearAnimationListener ( entry . exitAnimation ) ;
622
- clearAnimationListener ( entry . popEnterAnimation ) ;
623
+ // remove previous listener if we are changing the animator .
624
+ clearAnimationListener ( entry . exitAnimator , listener ) ;
625
+ clearAnimationListener ( entry . popEnterAnimator , listener ) ;
623
626
624
- const exitAnimation = < ExpandedAnimation > transition . createAndroidAnimation ( AndroidTransitionType . exit ) ;
625
- exitAnimation . transitionType = AndroidTransitionType . exit ;
626
- exitAnimation . entry = entry ;
627
- exitAnimation . setAnimationListener ( listener ) ;
628
- entry . exitAnimation = exitAnimation ;
627
+ const exitAnimator = < ExpandedAnimator > transition . createAndroidAnimator ( AndroidTransitionType . exit ) ;
628
+ exitAnimator . transitionType = AndroidTransitionType . exit ;
629
+ exitAnimator . entry = entry ;
630
+ exitAnimator . addListener ( listener ) ;
631
+ entry . exitAnimator = exitAnimator ;
629
632
630
- const popEnterAnimation = < ExpandedAnimation > transition . createAndroidAnimation ( AndroidTransitionType . popEnter ) ;
631
- popEnterAnimation . transitionType = AndroidTransitionType . popEnter ;
632
- popEnterAnimation . entry = entry ;
633
- popEnterAnimation . setAnimationListener ( listener ) ;
634
- entry . popEnterAnimation = popEnterAnimation ;
633
+ const popEnterAnimator = < ExpandedAnimator > transition . createAndroidAnimator ( AndroidTransitionType . popEnter ) ;
634
+ popEnterAnimator . transitionType = AndroidTransitionType . popEnter ;
635
+ popEnterAnimator . entry = entry ;
636
+ popEnterAnimator . addListener ( listener ) ;
637
+ entry . popEnterAnimator = popEnterAnimator ;
635
638
}
636
639
637
640
function setupAllAnimation ( entry : ExpandedEntry , transition : Transition ) : void {
@@ -640,33 +643,33 @@ function setupAllAnimation(entry: ExpandedEntry, transition: Transition): void {
640
643
641
644
// setupAllAnimation is called only for new fragments so we don't
642
645
// need to clearAnimationListener for enter & popExit animators.
643
- const enterAnimation = < ExpandedAnimation > transition . createAndroidAnimation ( AndroidTransitionType . enter ) ;
644
- enterAnimation . transitionType = AndroidTransitionType . enter ;
645
- enterAnimation . entry = entry ;
646
- enterAnimation . setAnimationListener ( listener ) ;
647
- entry . enterAnimation = enterAnimation ;
646
+ const enterAnimator = < ExpandedAnimator > transition . createAndroidAnimator ( AndroidTransitionType . enter ) ;
647
+ enterAnimator . transitionType = AndroidTransitionType . enter ;
648
+ enterAnimator . entry = entry ;
649
+ enterAnimator . addListener ( listener ) ;
650
+ entry . enterAnimator = enterAnimator ;
648
651
649
- const popExitAnimation = < ExpandedAnimation > transition . createAndroidAnimation ( AndroidTransitionType . popExit ) ;
650
- popExitAnimation . transitionType = AndroidTransitionType . popExit ;
651
- popExitAnimation . entry = entry ;
652
- popExitAnimation . setAnimationListener ( listener ) ;
653
- entry . popExitAnimation = popExitAnimation ;
652
+ const popExitAnimator = < ExpandedAnimator > transition . createAndroidAnimator ( AndroidTransitionType . popExit ) ;
653
+ popExitAnimator . transitionType = AndroidTransitionType . popExit ;
654
+ popExitAnimator . entry = entry ;
655
+ popExitAnimator . addListener ( listener ) ;
656
+ entry . popExitAnimator = popExitAnimator ;
654
657
}
655
658
656
659
function setupDefaultAnimations ( entry : ExpandedEntry , transition : Transition ) : void {
657
660
const listener = getAnimationListener ( ) ;
658
661
659
- const enterAnimation = < ExpandedAnimation > transition . createAndroidAnimation ( AndroidTransitionType . enter ) ;
660
- enterAnimation . transitionType = AndroidTransitionType . enter ;
661
- enterAnimation . entry = entry ;
662
- enterAnimation . setAnimationListener ( listener ) ;
663
- entry . defaultEnterAnimation = enterAnimation ;
662
+ const enterAnimator = < ExpandedAnimator > transition . createAndroidAnimator ( AndroidTransitionType . enter ) ;
663
+ enterAnimator . transitionType = AndroidTransitionType . enter ;
664
+ enterAnimator . entry = entry ;
665
+ enterAnimator . addListener ( listener ) ;
666
+ entry . defaultEnterAnimator = enterAnimator ;
664
667
665
- const exitAnimation = < ExpandedAnimation > transition . createAndroidAnimation ( AndroidTransitionType . exit ) ;
666
- exitAnimation . transitionType = AndroidTransitionType . exit ;
667
- exitAnimation . entry = entry ;
668
- exitAnimation . setAnimationListener ( listener ) ;
669
- entry . defaultExitAnimation = exitAnimation ;
668
+ const exitAnimator = < ExpandedAnimator > transition . createAndroidAnimator ( AndroidTransitionType . exit ) ;
669
+ exitAnimator . transitionType = AndroidTransitionType . exit ;
670
+ exitAnimator . entry = entry ;
671
+ exitAnimator . addListener ( listener ) ;
672
+ entry . defaultExitAnimator = exitAnimator ;
670
673
}
671
674
672
675
function setUpNativeTransition ( navigationTransition : NavigationTransition , nativeTransition : android . transition . Transition ) {
@@ -729,10 +732,10 @@ function printTransitions(entry: ExpandedEntry) {
729
732
}
730
733
731
734
if ( entry . transition ) {
732
- result += `enterAnimator=${ entry . enterAnimation } , ` ;
733
- result += `exitAnimator=${ entry . exitAnimation } , ` ;
734
- result += `popEnterAnimator=${ entry . popEnterAnimation } , ` ;
735
- result += `popExitAnimator=${ entry . popExitAnimation } , ` ;
735
+ result += `enterAnimator=${ entry . enterAnimator } , ` ;
736
+ result += `exitAnimator=${ entry . exitAnimator } , ` ;
737
+ result += `popEnterAnimator=${ entry . popEnterAnimator } , ` ;
738
+ result += `popExitAnimator=${ entry . popExitAnimator } , ` ;
736
739
}
737
740
if ( sdkVersion ( ) >= 21 ) {
738
741
const fragment = entry . fragment ;
@@ -745,16 +748,20 @@ function printTransitions(entry: ExpandedEntry) {
745
748
}
746
749
}
747
750
751
+ function javaObjectArray ( ...params : java . lang . Object [ ] ) {
752
+ const nativeArray = Array . create ( java . lang . Object , params . length ) ;
753
+ params . forEach ( ( value , i ) => nativeArray [ i ] = value ) ;
754
+ return nativeArray ;
755
+ }
756
+
757
+ function createDummyZeroDurationAnimator ( ) : android . animation . Animator {
758
+ const animator = android . animation . ValueAnimator . ofObject ( intEvaluator ( ) , javaObjectArray ( java . lang . Integer . valueOf ( 0 ) , java . lang . Integer . valueOf ( 1 ) ) ) ;
759
+ animator . setDuration ( 0 ) ;
760
+ return animator ;
761
+ }
762
+
748
763
class NoTransition extends Transition {
749
- public createAndroidAnimation ( transitionType : string ) : android . view . animation . Animation {
750
- const animation = new android . view . animation . AlphaAnimation ( 1 , 1 ) ;
751
- // NOTE: this should not be necessary when we revert to Animators API
752
- // HACK: Android view animation with zero duration seems to be buggy and raises animation listener events in illogical (wrong?) order:
753
- // "enter" start -> "enter" end -> "exit" start -> "exit" end;
754
- // we would expect events to overlap "exit" start -> "enter" start -> "exit" end -> "enter" end, or at least
755
- // "exit" start / end to be raised before "enter" start / end
756
- animation . setDuration ( 1 ) ;
757
-
758
- return animation ;
764
+ public createAndroidAnimator ( transitionType : string ) : android . animation . Animator {
765
+ return createDummyZeroDurationAnimator ( ) ;
759
766
}
760
767
}
0 commit comments