mirror of
https://github.com/NativeScript/NativeScript.git
synced 2025-08-17 04:41:36 +08:00
refactor: restore animators api usage (#6403)
This commit is contained in:
@ -5,9 +5,8 @@ export class CustomTransition extends transition.Transition {
|
|||||||
super(duration, curve);
|
super(duration, curve);
|
||||||
}
|
}
|
||||||
|
|
||||||
public createAndroidAnimation(transitionType: string): android.view.animation.Animation {
|
public createAndroidAnimator(transitionType: string): android.animation.Animator {
|
||||||
const scaleValues = [];
|
var scaleValues = Array.create("float", 2);
|
||||||
|
|
||||||
switch (transitionType) {
|
switch (transitionType) {
|
||||||
case transition.AndroidTransitionType.enter:
|
case transition.AndroidTransitionType.enter:
|
||||||
case transition.AndroidTransitionType.popEnter:
|
case transition.AndroidTransitionType.popEnter:
|
||||||
@ -20,22 +19,18 @@ export class CustomTransition extends transition.Transition {
|
|||||||
scaleValues[1] = 0;
|
scaleValues[1] = 0;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
var objectAnimators = Array.create(android.animation.Animator, 2);
|
||||||
const animationSet = new android.view.animation.AnimationSet(false);
|
objectAnimators[0] = android.animation.ObjectAnimator.ofFloat(null, "scaleX", scaleValues);
|
||||||
const duration = this.getDuration();
|
objectAnimators[1] = android.animation.ObjectAnimator.ofFloat(null, "scaleY", scaleValues);
|
||||||
|
var animatorSet = new android.animation.AnimatorSet();
|
||||||
|
animatorSet.playTogether(objectAnimators);
|
||||||
|
|
||||||
|
var duration = this.getDuration();
|
||||||
if (duration !== undefined) {
|
if (duration !== undefined) {
|
||||||
animationSet.setDuration(duration);
|
animatorSet.setDuration(duration);
|
||||||
}
|
}
|
||||||
|
animatorSet.setInterpolator(this.getCurve());
|
||||||
|
|
||||||
animationSet.setInterpolator(this.getCurve());
|
return animatorSet;
|
||||||
animationSet.addAnimation(
|
|
||||||
new android.view.animation.ScaleAnimation(
|
|
||||||
scaleValues[0],
|
|
||||||
scaleValues[1],
|
|
||||||
scaleValues[0],
|
|
||||||
scaleValues[1]
|
|
||||||
));
|
|
||||||
|
|
||||||
return animationSet;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -14,8 +14,9 @@ class FragmentClass extends android.support.v4.app.Fragment {
|
|||||||
this._callbacks.onHiddenChanged(this, hidden, super.onHiddenChanged);
|
this._callbacks.onHiddenChanged(this, hidden, super.onHiddenChanged);
|
||||||
}
|
}
|
||||||
|
|
||||||
public onCreateAnimation(transit: number, enter: boolean, nextAnim: number): android.view.animation.Animation {
|
public onCreateAnimator(transit: number, enter: boolean, nextAnim: number): android.animation.Animator {
|
||||||
return this._callbacks.onCreateAnimation(this, transit, enter, nextAnim, super.onCreateAnimation);
|
let result = this._callbacks.onCreateAnimator(this, transit, enter, nextAnim, super.onCreateAnimator);
|
||||||
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
public onStop(): void {
|
public onStop(): void {
|
||||||
|
@ -19,7 +19,7 @@ interface TransitionListener {
|
|||||||
new(entry: ExpandedEntry, transition: android.transition.Transition): ExpandedTransitionListener;
|
new(entry: ExpandedEntry, transition: android.transition.Transition): ExpandedTransitionListener;
|
||||||
}
|
}
|
||||||
|
|
||||||
interface ExpandedAnimation extends android.view.animation.Animation {
|
interface ExpandedAnimator extends android.animation.Animator {
|
||||||
entry: ExpandedEntry;
|
entry: ExpandedEntry;
|
||||||
transitionType?: string;
|
transitionType?: string;
|
||||||
}
|
}
|
||||||
@ -35,13 +35,13 @@ interface ExpandedEntry extends BackstackEntry {
|
|||||||
reenterTransitionListener: ExpandedTransitionListener;
|
reenterTransitionListener: ExpandedTransitionListener;
|
||||||
returnTransitionListener: ExpandedTransitionListener;
|
returnTransitionListener: ExpandedTransitionListener;
|
||||||
|
|
||||||
enterAnimation: ExpandedAnimation;
|
enterAnimator: ExpandedAnimator;
|
||||||
exitAnimation: ExpandedAnimation;
|
exitAnimator: ExpandedAnimator;
|
||||||
popEnterAnimation: ExpandedAnimation;
|
popEnterAnimator: ExpandedAnimator;
|
||||||
popExitAnimation: ExpandedAnimation;
|
popExitAnimator: ExpandedAnimator;
|
||||||
|
|
||||||
defaultEnterAnimation: ExpandedAnimation;
|
defaultEnterAnimator: ExpandedAnimator;
|
||||||
defaultExitAnimation: ExpandedAnimation;
|
defaultExitAnimator: ExpandedAnimator;
|
||||||
|
|
||||||
transition: Transition;
|
transition: Transition;
|
||||||
transitionName: string;
|
transitionName: string;
|
||||||
@ -49,13 +49,14 @@ interface ExpandedEntry extends BackstackEntry {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const sdkVersion = lazy(() => parseInt(device.sdkVersion));
|
const sdkVersion = lazy(() => parseInt(device.sdkVersion));
|
||||||
|
const intEvaluator = lazy(() => new android.animation.IntEvaluator());
|
||||||
const defaultInterpolator = lazy(() => new android.view.animation.AccelerateDecelerateInterpolator());
|
const defaultInterpolator = lazy(() => new android.view.animation.AccelerateDecelerateInterpolator());
|
||||||
|
|
||||||
export const waitingQueue = new Map<number, Set<ExpandedEntry>>();
|
export const waitingQueue = new Map<number, Set<ExpandedEntry>>();
|
||||||
export const completedEntries = new Map<number, ExpandedEntry>();
|
export const completedEntries = new Map<number, ExpandedEntry>();
|
||||||
|
|
||||||
let TransitionListener: TransitionListener;
|
let TransitionListener: TransitionListener;
|
||||||
let AnimationListener: android.view.animation.Animation.AnimationListener;
|
let AnimationListener: android.animation.Animator.AnimatorListener;
|
||||||
|
|
||||||
export function _setAndroidFragmentTransitions(
|
export function _setAndroidFragmentTransitions(
|
||||||
animated: boolean,
|
animated: boolean,
|
||||||
@ -170,39 +171,39 @@ export function _setAndroidFragmentTransitions(
|
|||||||
printTransitions(newEntry);
|
printTransitions(newEntry);
|
||||||
}
|
}
|
||||||
|
|
||||||
export function _onFragmentCreateAnimation(entry: ExpandedEntry, fragment: android.support.v4.app.Fragment, nextAnim: number, enter: boolean): android.view.animation.Animation {
|
export function _onFragmentCreateAnimator(entry: ExpandedEntry, fragment: android.support.v4.app.Fragment, nextAnim: number, enter: boolean): android.animation.Animator {
|
||||||
let animation: android.view.animation.Animation;
|
let animator: android.animation.Animator;
|
||||||
switch (nextAnim) {
|
switch (nextAnim) {
|
||||||
case AnimationType.enterFakeResourceId:
|
case AnimationType.enterFakeResourceId:
|
||||||
animation = entry.enterAnimation;
|
animator = entry.enterAnimator;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case AnimationType.exitFakeResourceId:
|
case AnimationType.exitFakeResourceId:
|
||||||
animation = entry.exitAnimation;
|
animator = entry.exitAnimator;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case AnimationType.popEnterFakeResourceId:
|
case AnimationType.popEnterFakeResourceId:
|
||||||
animation = entry.popEnterAnimation;
|
animator = entry.popEnterAnimator;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case AnimationType.popExitFakeResourceId:
|
case AnimationType.popExitFakeResourceId:
|
||||||
animation = entry.popExitAnimation;
|
animator = entry.popExitAnimator;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!animation && sdkVersion() >= 21) {
|
if (!animator && sdkVersion() >= 21) {
|
||||||
const view = fragment.getView();
|
const view = fragment.getView();
|
||||||
const jsParent = entry.resolvedPage.parent;
|
const jsParent = entry.resolvedPage.parent;
|
||||||
const parent = view.getParent() || (jsParent && jsParent.nativeViewProtected);
|
const parent = view.getParent() || (jsParent && jsParent.nativeViewProtected);
|
||||||
const animatedEntries = _getAnimatedEntries(entry.frameId);
|
const animatedEntries = _getAnimatedEntries(entry.frameId);
|
||||||
if (!animatedEntries || !animatedEntries.has(entry)) {
|
if (!animatedEntries || !animatedEntries.has(entry)) {
|
||||||
if (parent && !(<any>parent).isLaidOut()) {
|
if (parent && !(<any>parent).isLaidOut()) {
|
||||||
animation = enter ? entry.defaultEnterAnimation : entry.defaultExitAnimation;
|
animator = enter ? entry.defaultEnterAnimator : entry.defaultExitAnimator;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return animation;
|
return animator;
|
||||||
}
|
}
|
||||||
|
|
||||||
export function _getAnimatedEntries(frameId: number): Set<BackstackEntry> {
|
export function _getAnimatedEntries(frameId: number): Set<BackstackEntry> {
|
||||||
@ -312,40 +313,40 @@ function getTransitionListener(entry: ExpandedEntry, transition: android.transit
|
|||||||
return new TransitionListener(entry, transition);
|
return new TransitionListener(entry, transition);
|
||||||
}
|
}
|
||||||
|
|
||||||
function getAnimationListener(): android.view.animation.Animation.AnimationListener {
|
function getAnimationListener(): android.animation.Animator.AnimatorListener {
|
||||||
if (!AnimationListener) {
|
if (!AnimationListener) {
|
||||||
@Interfaces([android.view.animation.Animation.AnimationListener])
|
@Interfaces([android.animation.Animator.AnimatorListener])
|
||||||
class AnimationListenerImpl extends java.lang.Object implements android.view.animation.Animation.AnimationListener {
|
class AnimationListenerImpl extends java.lang.Object implements android.animation.Animator.AnimatorListener {
|
||||||
constructor() {
|
constructor() {
|
||||||
super();
|
super();
|
||||||
return global.__native(this);
|
return global.__native(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
onAnimationStart(animation: ExpandedAnimation): void {
|
onAnimationStart(animator: ExpandedAnimator): void {
|
||||||
const entry = animation.entry;
|
const entry = animator.entry;
|
||||||
addToWaitingQueue(entry);
|
addToWaitingQueue(entry);
|
||||||
if (traceEnabled()) {
|
if (traceEnabled()) {
|
||||||
traceWrite(`START ${animation.transitionType} for ${entry.fragmentTag}`, traceCategories.Transition);
|
traceWrite(`START ${animator.transitionType} for ${entry.fragmentTag}`, traceCategories.Transition);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
onAnimationRepeat(animation: ExpandedAnimation): void {
|
onAnimationRepeat(animator: ExpandedAnimator): void {
|
||||||
if (traceEnabled()) {
|
if (traceEnabled()) {
|
||||||
traceWrite(`REPEAT ${animation.transitionType} for ${animation.entry.fragmentTag}`, traceCategories.Transition);
|
traceWrite(`REPEAT ${animator.transitionType} for ${animator.entry.fragmentTag}`, traceCategories.Transition);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
onAnimationEnd(animation: ExpandedAnimation): void {
|
onAnimationEnd(animator: ExpandedAnimator): void {
|
||||||
if (traceEnabled()) {
|
if (traceEnabled()) {
|
||||||
traceWrite(`END ${animation.transitionType} for ${animation.entry.fragmentTag}`, traceCategories.Transition);
|
traceWrite(`END ${animator.transitionType} for ${animator.entry.fragmentTag}`, traceCategories.Transition);
|
||||||
}
|
}
|
||||||
|
|
||||||
transitionOrAnimationCompleted(animation.entry);
|
transitionOrAnimationCompleted(animator.entry);
|
||||||
}
|
}
|
||||||
|
|
||||||
onAnimationCancel(animation: ExpandedAnimation): void {
|
onAnimationCancel(animator: ExpandedAnimator): void {
|
||||||
if (traceEnabled()) {
|
if (traceEnabled()) {
|
||||||
traceWrite(`CANCEL ${animation.transitionType} for ${animation.entry.fragmentTag}`, traceCategories.Transition);
|
traceWrite(`CANCEL ${animator.transitionType} for ${animator.entry.fragmentTag}`, traceCategories.Transition);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -367,18 +368,19 @@ function addToWaitingQueue(entry: ExpandedEntry): void {
|
|||||||
entries.add(entry);
|
entries.add(entry);
|
||||||
}
|
}
|
||||||
|
|
||||||
function clearAnimationListener(animation: ExpandedAnimation): void {
|
function clearAnimationListener(animator: ExpandedAnimator, listener: android.animation.Animator.AnimatorListener): void {
|
||||||
if (!animation) {
|
if (!animator) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
animator.removeListener(listener);
|
||||||
|
|
||||||
if (traceEnabled()) {
|
if (traceEnabled()) {
|
||||||
const entry = animation.entry;
|
const entry = animator.entry;
|
||||||
traceWrite(`Clear ${animation.transitionType} - ${entry.transition} for ${entry.fragmentTag}`, traceCategories.Transition);
|
traceWrite(`Clear ${animator.transitionType} - ${entry.transition} for ${entry.fragmentTag}`, traceCategories.Transition);
|
||||||
}
|
}
|
||||||
|
|
||||||
animation.setAnimationListener(null);
|
animator.entry = null;
|
||||||
animation.entry = null;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function clearExitAndReenterTransitions(entry: ExpandedEntry, removeListener: boolean): void {
|
function clearExitAndReenterTransitions(entry: ExpandedEntry, removeListener: boolean): void {
|
||||||
@ -477,10 +479,11 @@ function clearEntry(entry: ExpandedEntry, removeListener: boolean): void {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (removeListener) {
|
if (removeListener) {
|
||||||
clearAnimationListener(entry.enterAnimation);
|
const listener = getAnimationListener();
|
||||||
clearAnimationListener(entry.exitAnimation);
|
clearAnimationListener(entry.enterAnimator, listener);
|
||||||
clearAnimationListener(entry.popEnterAnimation);
|
clearAnimationListener(entry.exitAnimator, listener);
|
||||||
clearAnimationListener(entry.popExitAnimation);
|
clearAnimationListener(entry.popEnterAnimator, listener);
|
||||||
|
clearAnimationListener(entry.popExitAnimator, listener);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -617,21 +620,21 @@ function setupNewFragmentExplodeTransition(navTransition: NavigationTransition,
|
|||||||
function setupExitAndPopEnterAnimation(entry: ExpandedEntry, transition: Transition): void {
|
function setupExitAndPopEnterAnimation(entry: ExpandedEntry, transition: Transition): void {
|
||||||
const listener = getAnimationListener();
|
const listener = getAnimationListener();
|
||||||
|
|
||||||
// remove previous listener if we are changing the animation.
|
// remove previous listener if we are changing the animator.
|
||||||
clearAnimationListener(entry.exitAnimation);
|
clearAnimationListener(entry.exitAnimator, listener);
|
||||||
clearAnimationListener(entry.popEnterAnimation);
|
clearAnimationListener(entry.popEnterAnimator, listener);
|
||||||
|
|
||||||
const exitAnimation = <ExpandedAnimation>transition.createAndroidAnimation(AndroidTransitionType.exit);
|
const exitAnimator = <ExpandedAnimator>transition.createAndroidAnimator(AndroidTransitionType.exit);
|
||||||
exitAnimation.transitionType = AndroidTransitionType.exit;
|
exitAnimator.transitionType = AndroidTransitionType.exit;
|
||||||
exitAnimation.entry = entry;
|
exitAnimator.entry = entry;
|
||||||
exitAnimation.setAnimationListener(listener);
|
exitAnimator.addListener(listener);
|
||||||
entry.exitAnimation = exitAnimation;
|
entry.exitAnimator = exitAnimator;
|
||||||
|
|
||||||
const popEnterAnimation = <ExpandedAnimation>transition.createAndroidAnimation(AndroidTransitionType.popEnter);
|
const popEnterAnimator = <ExpandedAnimator>transition.createAndroidAnimator(AndroidTransitionType.popEnter);
|
||||||
popEnterAnimation.transitionType = AndroidTransitionType.popEnter;
|
popEnterAnimator.transitionType = AndroidTransitionType.popEnter;
|
||||||
popEnterAnimation.entry = entry;
|
popEnterAnimator.entry = entry;
|
||||||
popEnterAnimation.setAnimationListener(listener);
|
popEnterAnimator.addListener(listener);
|
||||||
entry.popEnterAnimation = popEnterAnimation;
|
entry.popEnterAnimator = popEnterAnimator;
|
||||||
}
|
}
|
||||||
|
|
||||||
function setupAllAnimation(entry: ExpandedEntry, transition: Transition): void {
|
function setupAllAnimation(entry: ExpandedEntry, transition: Transition): void {
|
||||||
@ -640,33 +643,33 @@ function setupAllAnimation(entry: ExpandedEntry, transition: Transition): void {
|
|||||||
|
|
||||||
// setupAllAnimation is called only for new fragments so we don't
|
// setupAllAnimation is called only for new fragments so we don't
|
||||||
// need to clearAnimationListener for enter & popExit animators.
|
// need to clearAnimationListener for enter & popExit animators.
|
||||||
const enterAnimation = <ExpandedAnimation>transition.createAndroidAnimation(AndroidTransitionType.enter);
|
const enterAnimator = <ExpandedAnimator>transition.createAndroidAnimator(AndroidTransitionType.enter);
|
||||||
enterAnimation.transitionType = AndroidTransitionType.enter;
|
enterAnimator.transitionType = AndroidTransitionType.enter;
|
||||||
enterAnimation.entry = entry;
|
enterAnimator.entry = entry;
|
||||||
enterAnimation.setAnimationListener(listener);
|
enterAnimator.addListener(listener);
|
||||||
entry.enterAnimation = enterAnimation;
|
entry.enterAnimator = enterAnimator;
|
||||||
|
|
||||||
const popExitAnimation = <ExpandedAnimation>transition.createAndroidAnimation(AndroidTransitionType.popExit);
|
const popExitAnimator = <ExpandedAnimator>transition.createAndroidAnimator(AndroidTransitionType.popExit);
|
||||||
popExitAnimation.transitionType = AndroidTransitionType.popExit;
|
popExitAnimator.transitionType = AndroidTransitionType.popExit;
|
||||||
popExitAnimation.entry = entry;
|
popExitAnimator.entry = entry;
|
||||||
popExitAnimation.setAnimationListener(listener);
|
popExitAnimator.addListener(listener);
|
||||||
entry.popExitAnimation = popExitAnimation;
|
entry.popExitAnimator = popExitAnimator;
|
||||||
}
|
}
|
||||||
|
|
||||||
function setupDefaultAnimations(entry: ExpandedEntry, transition: Transition): void {
|
function setupDefaultAnimations(entry: ExpandedEntry, transition: Transition): void {
|
||||||
const listener = getAnimationListener();
|
const listener = getAnimationListener();
|
||||||
|
|
||||||
const enterAnimation = <ExpandedAnimation>transition.createAndroidAnimation(AndroidTransitionType.enter);
|
const enterAnimator = <ExpandedAnimator>transition.createAndroidAnimator(AndroidTransitionType.enter);
|
||||||
enterAnimation.transitionType = AndroidTransitionType.enter;
|
enterAnimator.transitionType = AndroidTransitionType.enter;
|
||||||
enterAnimation.entry = entry;
|
enterAnimator.entry = entry;
|
||||||
enterAnimation.setAnimationListener(listener);
|
enterAnimator.addListener(listener);
|
||||||
entry.defaultEnterAnimation = enterAnimation;
|
entry.defaultEnterAnimator = enterAnimator;
|
||||||
|
|
||||||
const exitAnimation = <ExpandedAnimation>transition.createAndroidAnimation(AndroidTransitionType.exit);
|
const exitAnimator = <ExpandedAnimator>transition.createAndroidAnimator(AndroidTransitionType.exit);
|
||||||
exitAnimation.transitionType = AndroidTransitionType.exit;
|
exitAnimator.transitionType = AndroidTransitionType.exit;
|
||||||
exitAnimation.entry = entry;
|
exitAnimator.entry = entry;
|
||||||
exitAnimation.setAnimationListener(listener);
|
exitAnimator.addListener(listener);
|
||||||
entry.defaultExitAnimation = exitAnimation;
|
entry.defaultExitAnimator = exitAnimator;
|
||||||
}
|
}
|
||||||
|
|
||||||
function setUpNativeTransition(navigationTransition: NavigationTransition, nativeTransition: android.transition.Transition) {
|
function setUpNativeTransition(navigationTransition: NavigationTransition, nativeTransition: android.transition.Transition) {
|
||||||
@ -729,10 +732,10 @@ function printTransitions(entry: ExpandedEntry) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (entry.transition) {
|
if (entry.transition) {
|
||||||
result += `enterAnimator=${entry.enterAnimation}, `;
|
result += `enterAnimator=${entry.enterAnimator}, `;
|
||||||
result += `exitAnimator=${entry.exitAnimation}, `;
|
result += `exitAnimator=${entry.exitAnimator}, `;
|
||||||
result += `popEnterAnimator=${entry.popEnterAnimation}, `;
|
result += `popEnterAnimator=${entry.popEnterAnimator}, `;
|
||||||
result += `popExitAnimator=${entry.popExitAnimation}, `;
|
result += `popExitAnimator=${entry.popExitAnimator}, `;
|
||||||
}
|
}
|
||||||
if (sdkVersion() >= 21) {
|
if (sdkVersion() >= 21) {
|
||||||
const fragment = entry.fragment;
|
const fragment = entry.fragment;
|
||||||
@ -745,16 +748,20 @@ function printTransitions(entry: ExpandedEntry) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class NoTransition extends Transition {
|
function javaObjectArray(...params: java.lang.Object[]) {
|
||||||
public createAndroidAnimation(transitionType: string): android.view.animation.Animation {
|
const nativeArray = Array.create(java.lang.Object, params.length);
|
||||||
const animation = new android.view.animation.AlphaAnimation(1, 1);
|
params.forEach((value, i) => nativeArray[i] = value);
|
||||||
// NOTE: this should not be necessary when we revert to Animators API
|
return nativeArray;
|
||||||
// HACK: Android view animation with zero duration seems to be buggy and raises animation listener events in illogical (wrong?) order:
|
}
|
||||||
// "enter" start -> "enter" end -> "exit" start -> "exit" end;
|
|
||||||
// we would expect events to overlap "exit" start -> "enter" start -> "exit" end -> "enter" end, or at least
|
|
||||||
// "exit" start / end to be raised before "enter" start / end
|
|
||||||
animation.setDuration(1);
|
|
||||||
|
|
||||||
return animation;
|
function createDummyZeroDurationAnimator(): android.animation.Animator {
|
||||||
|
const animator = android.animation.ValueAnimator.ofObject(intEvaluator(), javaObjectArray(java.lang.Integer.valueOf(0), java.lang.Integer.valueOf(1)));
|
||||||
|
animator.setDuration(0);
|
||||||
|
return animator;
|
||||||
|
}
|
||||||
|
|
||||||
|
class NoTransition extends Transition {
|
||||||
|
public createAndroidAnimator(transitionType: string): android.animation.Animator {
|
||||||
|
return createDummyZeroDurationAnimator();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -28,7 +28,7 @@ export function _setAndroidFragmentTransitions(
|
|||||||
/**
|
/**
|
||||||
* @private
|
* @private
|
||||||
*/
|
*/
|
||||||
export function _onFragmentCreateAnimation(entry: BackstackEntry, fragment: any, nextAnim: number, enter: boolean): any;
|
export function _onFragmentCreateAnimator(entry: BackstackEntry, fragment: any, nextAnim: number, enter: boolean): any;
|
||||||
/**
|
/**
|
||||||
* @private
|
* @private
|
||||||
*/
|
*/
|
||||||
|
@ -13,7 +13,7 @@ import {
|
|||||||
} from "./frame-common";
|
} from "./frame-common";
|
||||||
|
|
||||||
import {
|
import {
|
||||||
_setAndroidFragmentTransitions, _onFragmentCreateAnimation, _getAnimatedEntries,
|
_setAndroidFragmentTransitions, _onFragmentCreateAnimator, _getAnimatedEntries,
|
||||||
_updateTransitions, _reverseTransitions, _clearEntry, _clearFragment, AnimationType
|
_updateTransitions, _reverseTransitions, _clearEntry, _clearFragment, AnimationType
|
||||||
} from "./fragment.transitions";
|
} from "./fragment.transitions";
|
||||||
|
|
||||||
@ -667,7 +667,7 @@ class FragmentCallbacksImplementation implements AndroidFragmentCallbacks {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@profile
|
@profile
|
||||||
public onCreateAnimation(fragment: android.support.v4.app.Fragment, transit: number, enter: boolean, nextAnim: number, superFunc: Function): android.view.animation.Animation {
|
public onCreateAnimator(fragment: android.support.v4.app.Fragment, transit: number, enter: boolean, nextAnim: number, superFunc: Function): android.animation.Animator {
|
||||||
let nextAnimString: string;
|
let nextAnimString: string;
|
||||||
switch (nextAnim) {
|
switch (nextAnim) {
|
||||||
case AnimationType.enterFakeResourceId: nextAnimString = "enter"; break;
|
case AnimationType.enterFakeResourceId: nextAnimString = "enter"; break;
|
||||||
@ -676,16 +676,16 @@ class FragmentCallbacksImplementation implements AndroidFragmentCallbacks {
|
|||||||
case AnimationType.popExitFakeResourceId: nextAnimString = "popExit"; break;
|
case AnimationType.popExitFakeResourceId: nextAnimString = "popExit"; break;
|
||||||
}
|
}
|
||||||
|
|
||||||
let animation = _onFragmentCreateAnimation(this.entry, fragment, nextAnim, enter);
|
let animator = _onFragmentCreateAnimator(this.entry, fragment, nextAnim, enter);
|
||||||
if (!animation) {
|
if (!animator) {
|
||||||
animation = superFunc.call(fragment, transit, enter, nextAnim);
|
animator = superFunc.call(fragment, transit, enter, nextAnim);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (traceEnabled()) {
|
if (traceEnabled()) {
|
||||||
traceWrite(`${fragment}.onCreateAnimation(${transit}, ${enter ? "enter" : "exit"}, ${nextAnimString}): ${animation ? "animation" : "no animation"}`, traceCategories.NativeLifecycle);
|
traceWrite(`${fragment}.onCreateAnimator(${transit}, ${enter ? "enter" : "exit"}, ${nextAnimString}): ${animator ? "animator" : "no animator"}`, traceCategories.NativeLifecycle);
|
||||||
}
|
}
|
||||||
|
|
||||||
return animation;
|
return animator;
|
||||||
}
|
}
|
||||||
|
|
||||||
@profile
|
@profile
|
||||||
|
2
tns-core-modules/ui/frame/frame.d.ts
vendored
2
tns-core-modules/ui/frame/frame.d.ts
vendored
@ -414,7 +414,7 @@ export interface AndroidActivityCallbacks {
|
|||||||
|
|
||||||
export interface AndroidFragmentCallbacks {
|
export interface AndroidFragmentCallbacks {
|
||||||
onHiddenChanged(fragment: any, hidden: boolean, superFunc: Function): void;
|
onHiddenChanged(fragment: any, hidden: boolean, superFunc: Function): void;
|
||||||
onCreateAnimation(fragment: any, transit: number, enter: boolean, nextAnim: number, superFunc: Function): any;
|
onCreateAnimator(fragment: any, transit: number, enter: boolean, nextAnim: number, superFunc: Function): any;
|
||||||
onCreate(fragment: any, savedInstanceState: any, superFunc: Function): void;
|
onCreate(fragment: any, savedInstanceState: any, superFunc: Function): void;
|
||||||
onCreateView(fragment: any, inflater: any, container: any, savedInstanceState: any, superFunc: Function): any;
|
onCreateView(fragment: any, inflater: any, container: any, savedInstanceState: any, superFunc: Function): any;
|
||||||
onSaveInstanceState(fragment: any, outState: any, superFunc: Function): void;
|
onSaveInstanceState(fragment: any, outState: any, superFunc: Function): void;
|
||||||
|
@ -1,29 +1,28 @@
|
|||||||
import { Transition, AndroidTransitionType } from "./transition";
|
import { Transition, AndroidTransitionType } from "./transition";
|
||||||
|
|
||||||
export class FadeTransition extends Transition {
|
export class FadeTransition extends Transition {
|
||||||
public createAndroidAnimation(transitionType: string): android.view.animation.Animation {
|
public createAndroidAnimator(transitionType: string): android.animation.Animator {
|
||||||
const alphaValues = [];
|
const alphaValues = Array.create("float", 2);
|
||||||
switch (transitionType) {
|
switch (transitionType) {
|
||||||
case AndroidTransitionType.enter:
|
case AndroidTransitionType.enter:
|
||||||
case AndroidTransitionType.popEnter:
|
case AndroidTransitionType.popEnter:
|
||||||
alphaValues[0] = 0.0;
|
alphaValues[0] = 0;
|
||||||
alphaValues[1] = 1.0;
|
alphaValues[1] = 1;
|
||||||
break;
|
break;
|
||||||
case AndroidTransitionType.exit:
|
case AndroidTransitionType.exit:
|
||||||
case AndroidTransitionType.popExit:
|
case AndroidTransitionType.popExit:
|
||||||
alphaValues[0] = 1.0;
|
alphaValues[0] = 1;
|
||||||
alphaValues[1] = 0.0;
|
alphaValues[1] = 0;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
const animation = new android.view.animation.AlphaAnimation(alphaValues[0], alphaValues[1]);
|
const animator = android.animation.ObjectAnimator.ofFloat(null, "alpha", alphaValues);
|
||||||
const duration = this.getDuration();
|
const duration = this.getDuration();
|
||||||
if (duration !== undefined) {
|
if (duration !== undefined) {
|
||||||
animation.setDuration(duration);
|
animator.setDuration(duration);
|
||||||
}
|
}
|
||||||
|
|
||||||
animation.setInterpolator(this.getCurve());
|
animator.setInterpolator(this.getCurve());
|
||||||
|
return animator;
|
||||||
return animation;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
import { Transition, AndroidTransitionType } from "./transition";
|
import { Transition, AndroidTransitionType } from "./transition";
|
||||||
|
|
||||||
// http://developer.android.com/training/animation/cardflip.html
|
//http://developer.android.com/training/animation/cardflip.html
|
||||||
export class FlipTransition extends Transition {
|
export class FlipTransition extends Transition {
|
||||||
private _direction: string;
|
private _direction: string;
|
||||||
|
|
||||||
@ -9,117 +9,109 @@ export class FlipTransition extends Transition {
|
|||||||
this._direction = direction;
|
this._direction = direction;
|
||||||
}
|
}
|
||||||
|
|
||||||
public createAndroidAnimation(transitionType: string): android.view.animation.Animation {
|
public createAndroidAnimator(transitionType: string): android.animation.Animator {
|
||||||
ensureRotate3dAnimationClass();
|
let objectAnimators;
|
||||||
|
let values;
|
||||||
let animation: android.view.animation.Animation;
|
let animator: android.animation.ObjectAnimator;
|
||||||
let animationSet: android.view.animation.AnimationSet
|
const animatorSet = new android.animation.AnimatorSet();
|
||||||
let rotateAnimation: android.view.animation.Animation;
|
|
||||||
let alphaAnimation: android.view.animation.Animation;
|
|
||||||
const fullDuration = this.getDuration() || 300;
|
const fullDuration = this.getDuration() || 300;
|
||||||
const interpolator = this.getCurve();
|
const interpolator = this.getCurve();
|
||||||
const rotationY = this._direction === "right" ? 180 : -180;
|
const rotationY = this._direction === "right" ? 180 : -180;
|
||||||
|
|
||||||
switch (transitionType) {
|
switch (transitionType) {
|
||||||
case AndroidTransitionType.enter: // card_flip_right_in
|
case AndroidTransitionType.enter: // card_flip_right_in
|
||||||
animation = new Rotate3dAnimationClass(rotationY, 0.0, 0.5, 0.5);
|
objectAnimators = Array.create(android.animation.Animator, 3);
|
||||||
animation.setInterpolator(interpolator);
|
|
||||||
animation.setDuration(fullDuration);
|
values = Array.create("float", 2);
|
||||||
|
values[0] = 1.0;
|
||||||
|
values[1] = 0.0;
|
||||||
|
animator = android.animation.ObjectAnimator.ofFloat(null, "alpha", values);
|
||||||
|
animator.setDuration(0);
|
||||||
|
objectAnimators[0] = animator;
|
||||||
|
|
||||||
|
values = Array.create("float", 2);
|
||||||
|
values[0] = rotationY;
|
||||||
|
values[1] = 0.0;
|
||||||
|
animator = android.animation.ObjectAnimator.ofFloat(null, "rotationY", values);
|
||||||
|
animator.setInterpolator(interpolator);
|
||||||
|
animator.setDuration(fullDuration);
|
||||||
|
objectAnimators[1] = animator;
|
||||||
|
|
||||||
|
values = Array.create("float", 2);
|
||||||
|
values[0] = 0.0;
|
||||||
|
values[1] = 1.0;
|
||||||
|
animator = android.animation.ObjectAnimator.ofFloat(null, "alpha", values);
|
||||||
|
animator.setStartDelay(fullDuration / 2);
|
||||||
|
animator.setDuration(1);
|
||||||
|
objectAnimators[2] = animator;
|
||||||
break;
|
break;
|
||||||
case AndroidTransitionType.exit: // card_flip_right_out
|
case AndroidTransitionType.exit: // card_flip_right_out
|
||||||
animation = animationSet = new android.view.animation.AnimationSet(false /* shareInterpolator */);
|
objectAnimators = Array.create(android.animation.Animator, 2);
|
||||||
|
|
||||||
rotateAnimation = new Rotate3dAnimationClass(0.0, -rotationY, 0.5, 0.5);
|
|
||||||
rotateAnimation.setInterpolator(interpolator);
|
|
||||||
rotateAnimation.setDuration(fullDuration);
|
|
||||||
animationSet.addAnimation(rotateAnimation);
|
|
||||||
|
|
||||||
alphaAnimation = new android.view.animation.AlphaAnimation(1.0, 0.0);
|
values = Array.create("float", 2);
|
||||||
alphaAnimation.setStartOffset(fullDuration / 2);
|
values[0] = 0.0;
|
||||||
alphaAnimation.setDuration(1);
|
values[1] = -rotationY;
|
||||||
animationSet.addAnimation(alphaAnimation);
|
animator = android.animation.ObjectAnimator.ofFloat(null, "rotationY", values);
|
||||||
|
animator.setInterpolator(interpolator);
|
||||||
|
animator.setDuration(fullDuration);
|
||||||
|
objectAnimators[0] = animator;
|
||||||
|
|
||||||
|
values = Array.create("float", 2);
|
||||||
|
values[0] = 1.0;
|
||||||
|
values[1] = 0.0;
|
||||||
|
animator = android.animation.ObjectAnimator.ofFloat(null, "alpha", values);
|
||||||
|
animator.setStartDelay(fullDuration / 2);
|
||||||
|
animator.setDuration(1);
|
||||||
|
objectAnimators[1] = animator;
|
||||||
break;
|
break;
|
||||||
case AndroidTransitionType.popEnter: // card_flip_left_in
|
case AndroidTransitionType.popEnter: // card_flip_left_in
|
||||||
animation = new Rotate3dAnimationClass(-rotationY, 0.0, 0.5, 0.5);
|
objectAnimators = Array.create(android.animation.Animator, 3);
|
||||||
animation.setInterpolator(interpolator);
|
|
||||||
animation.setDuration(fullDuration);
|
values = Array.create("float", 2);
|
||||||
|
values[0] = 1.0;
|
||||||
|
values[1] = 0.0;
|
||||||
|
animator = android.animation.ObjectAnimator.ofFloat(null, "alpha", values);
|
||||||
|
animator.setDuration(0);
|
||||||
|
objectAnimators[0] = animator;
|
||||||
|
|
||||||
|
values = Array.create("float", 2);
|
||||||
|
values[0] = -rotationY;
|
||||||
|
values[1] = 0.0;
|
||||||
|
animator = android.animation.ObjectAnimator.ofFloat(null, "rotationY", values);
|
||||||
|
animator.setInterpolator(interpolator);
|
||||||
|
animator.setDuration(fullDuration);
|
||||||
|
objectAnimators[1] = animator;
|
||||||
|
|
||||||
|
values = Array.create("float", 2);
|
||||||
|
values[0] = 0.0;
|
||||||
|
values[1] = 1.0;
|
||||||
|
animator = android.animation.ObjectAnimator.ofFloat(null, "alpha", values);
|
||||||
|
animator.setStartDelay(fullDuration / 2);
|
||||||
|
animator.setDuration(1);
|
||||||
|
objectAnimators[2] = animator;
|
||||||
break;
|
break;
|
||||||
case AndroidTransitionType.popExit: // card_flip_left_out
|
case AndroidTransitionType.popExit: // card_flip_left_out
|
||||||
animation = animationSet = new android.view.animation.AnimationSet(false /* shareInterpolator */);
|
objectAnimators = Array.create(android.animation.Animator, 2);
|
||||||
|
|
||||||
rotateAnimation = new Rotate3dAnimationClass(0.0, rotationY, 0.5, 0.5);
|
|
||||||
rotateAnimation.setInterpolator(interpolator);
|
|
||||||
rotateAnimation.setDuration(fullDuration);
|
|
||||||
animationSet.addAnimation(rotateAnimation);
|
|
||||||
|
|
||||||
alphaAnimation = new android.view.animation.AlphaAnimation(1.0, 0.0);
|
values = Array.create("float", 2);
|
||||||
alphaAnimation.setStartOffset(fullDuration / 2);
|
values[0] = 0.0;
|
||||||
alphaAnimation.setDuration(1);
|
values[1] = rotationY;
|
||||||
animationSet.addAnimation(alphaAnimation);
|
animator = android.animation.ObjectAnimator.ofFloat(null, "rotationY", values);
|
||||||
|
animator.setInterpolator(interpolator);
|
||||||
|
animator.setDuration(fullDuration);
|
||||||
|
objectAnimators[0] = animator;
|
||||||
|
|
||||||
|
values = Array.create("float", 2);
|
||||||
|
values[0] = 1.0;
|
||||||
|
values[1] = 0.0;
|
||||||
|
animator = android.animation.ObjectAnimator.ofFloat(null, "alpha", values);
|
||||||
|
animator.setStartDelay(fullDuration / 2);
|
||||||
|
animator.setDuration(1);
|
||||||
|
objectAnimators[1] = animator;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
return animation;
|
animatorSet.playTogether(objectAnimators);
|
||||||
|
return animatorSet;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
let Rotate3dAnimationClass;
|
|
||||||
function ensureRotate3dAnimationClass() {
|
|
||||||
if (Rotate3dAnimationClass) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Creates a new 3D rotation on the Y axis. The rotation is defined by its
|
|
||||||
* start angle and its end angle. Both angles are in degrees. The rotation
|
|
||||||
* is performed around a center point on the 2D space, definied by a pair
|
|
||||||
* of X and Y coordinates, called centerX and centerY.
|
|
||||||
*
|
|
||||||
* @param fromDegrees the start angle of the 3D rotation
|
|
||||||
* @param toDegrees the end angle of the 3D rotation
|
|
||||||
* @param centerX the X center of the 3D rotation (relative to self)
|
|
||||||
* @param centerY the Y center of the 3D rotation (relative to self)
|
|
||||||
*/
|
|
||||||
class Rotate3dAnimation extends android.view.animation.Animation {
|
|
||||||
private _camera: android.graphics.Camera;
|
|
||||||
private _pivotX: number;
|
|
||||||
private _pivotY: number;
|
|
||||||
|
|
||||||
constructor(
|
|
||||||
private _fromDegrees: number,
|
|
||||||
private _toDegrees: number,
|
|
||||||
private _centerX: number,
|
|
||||||
private _centerY: number) {
|
|
||||||
super();
|
|
||||||
return global.__native(this);
|
|
||||||
}
|
|
||||||
|
|
||||||
public initialize(width: number, height: number, parentWidth: number, parentHeight: number) {
|
|
||||||
super.initialize(width, height, parentWidth, parentHeight);
|
|
||||||
this._pivotX = this.resolveSize(android.view.animation.Animation.RELATIVE_TO_SELF, this._centerX, width, parentWidth);
|
|
||||||
this._pivotY = this.resolveSize(android.view.animation.Animation.RELATIVE_TO_SELF, this._centerY, height, parentHeight);
|
|
||||||
this._camera = new android.graphics.Camera();
|
|
||||||
}
|
|
||||||
|
|
||||||
public applyTransformation(interpolatedTime: number, t: android.view.animation.Transformation) {
|
|
||||||
const fromDegrees = this._fromDegrees;
|
|
||||||
const degrees = fromDegrees + ((this._toDegrees - fromDegrees) * interpolatedTime);
|
|
||||||
|
|
||||||
const pivotX = this._pivotX;
|
|
||||||
const pivotY = this._pivotY;
|
|
||||||
const camera = this._camera;
|
|
||||||
|
|
||||||
const matrix: android.graphics.Matrix = t.getMatrix();
|
|
||||||
|
|
||||||
camera.save();
|
|
||||||
camera.rotateY(degrees);
|
|
||||||
camera.getMatrix(matrix);
|
|
||||||
camera.restore();
|
|
||||||
|
|
||||||
matrix.preTranslate(-pivotX, -pivotY);
|
|
||||||
matrix.postTranslate(pivotX, pivotY);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Rotate3dAnimationClass = Rotate3dAnimation;
|
|
||||||
}
|
|
@ -13,8 +13,8 @@ export class SlideTransition extends transition.Transition {
|
|||||||
this._direction = direction;
|
this._direction = direction;
|
||||||
}
|
}
|
||||||
|
|
||||||
public createAndroidAnimation(transitionType: string): android.view.animation.Animation {
|
public createAndroidAnimator(transitionType: string): android.animation.Animator {
|
||||||
const translationValues = [];
|
const translationValues = Array.create("float", 2);
|
||||||
switch (this._direction) {
|
switch (this._direction) {
|
||||||
case "left":
|
case "left":
|
||||||
switch (transitionType) {
|
switch (transitionType) {
|
||||||
@ -98,22 +98,22 @@ export class SlideTransition extends transition.Transition {
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
let animation;
|
let prop;
|
||||||
|
|
||||||
if (this._direction === "left" || this._direction === "right") {
|
if (this._direction === "left" || this._direction === "right") {
|
||||||
animation = new android.view.animation.TranslateAnimation(translationValues[0], translationValues[1], 0, 0);
|
prop = "translationX";
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
animation = new android.view.animation.TranslateAnimation(0, 0, translationValues[0], translationValues[1]);
|
prop = "translationY";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const animator = android.animation.ObjectAnimator.ofFloat(null, prop, translationValues);
|
||||||
const duration = this.getDuration();
|
const duration = this.getDuration();
|
||||||
if (duration !== undefined) {
|
if (duration !== undefined) {
|
||||||
animation.setDuration(duration);
|
animator.setDuration(duration);
|
||||||
}
|
}
|
||||||
|
animator.setInterpolator(this.getCurve());
|
||||||
animation.setInterpolator(this.getCurve());
|
return animator;
|
||||||
|
|
||||||
return animation;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public toString(): string {
|
public toString(): string {
|
||||||
|
@ -38,7 +38,7 @@ export class Transition implements TransitionDefinition {
|
|||||||
throw new Error("Abstract method call");
|
throw new Error("Abstract method call");
|
||||||
}
|
}
|
||||||
|
|
||||||
public createAndroidAnimation(transitionType: string): android.view.animation.Animation {
|
public createAndroidAnimator(transitionType: string): android.animation.Animator {
|
||||||
throw new Error("Abstract method call");
|
throw new Error("Abstract method call");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -14,6 +14,6 @@ export class Transition {
|
|||||||
public getDuration(): number;
|
public getDuration(): number;
|
||||||
public getCurve(): any;
|
public getCurve(): any;
|
||||||
public animateIOSTransition(containerView: any, fromView: any, toView: any, operation: any, completion: (finished: boolean) => void): void;
|
public animateIOSTransition(containerView: any, fromView: any, toView: any, operation: any, completion: (finished: boolean) => void): void;
|
||||||
public createAndroidAnimation(transitionType: string): any;
|
public createAndroidAnimator(transitionType: string): any;
|
||||||
public toString(): string;
|
public toString(): string;
|
||||||
}
|
}
|
@ -24,7 +24,7 @@ export class Transition implements TransitionDefinition {
|
|||||||
throw new Error("Abstract method call");
|
throw new Error("Abstract method call");
|
||||||
}
|
}
|
||||||
|
|
||||||
public createAndroidAnimation(transitionType: string): any {
|
public createAndroidAnimator(transitionType: string): any {
|
||||||
throw new Error("Abstract method call");
|
throw new Error("Abstract method call");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user