diff --git a/CrossPlatformModules.csproj b/CrossPlatformModules.csproj index 7703aa599..e482543f8 100644 --- a/CrossPlatformModules.csproj +++ b/CrossPlatformModules.csproj @@ -1038,6 +1038,8 @@ + + utils.d.ts diff --git a/tsconfig.json b/tsconfig.json index f5a0260d4..8469c668c 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -703,6 +703,8 @@ "ui/web-view/web-view.ios.ts", "utils/debug.d.ts", "utils/debug.ts", + "utils/lazy.d.ts", + "utils/lazy.ts", "utils/module-merge.ts", "utils/number-utils.ts", "utils/types.d.ts", diff --git a/ui/animation/animation.android.ts b/ui/animation/animation.android.ts index d19a11c05..0ca2264a1 100644 --- a/ui/animation/animation.android.ts +++ b/ui/animation/animation.android.ts @@ -6,6 +6,7 @@ import trace = require("trace"); import types = require("utils/types"); import enums = require("ui/enums"); import styleModule = require("ui/styling/style"); +import lazy from "utils/lazy"; global.moduleMerge(common, exports); @@ -359,28 +360,28 @@ export class Animation extends common.Animation implements definition.Animation } } -let easeIn = new android.view.animation.AccelerateInterpolator(1); -let easeOut = new android.view.animation.DecelerateInterpolator(1); -let easeInOut = new android.view.animation.AccelerateDecelerateInterpolator(); -let linear = new android.view.animation.LinearInterpolator(); -let bounce = new android.view.animation.BounceInterpolator(); +let easeIn = lazy(() => new android.view.animation.AccelerateInterpolator(1)); +let easeOut = lazy(() => new android.view.animation.DecelerateInterpolator(1)); +let easeInOut = lazy(() => new android.view.animation.AccelerateDecelerateInterpolator()); +let linear = lazy(() => new android.view.animation.LinearInterpolator()); +let bounce = lazy(() => new android.view.animation.BounceInterpolator()); export function _resolveAnimationCurve(curve: any): any { switch (curve) { case enums.AnimationCurve.easeIn: trace.write("Animation curve resolved to android.view.animation.AccelerateInterpolator(1).", trace.categories.Animation); - return easeIn; + return easeIn(); case enums.AnimationCurve.easeOut: trace.write("Animation curve resolved to android.view.animation.DecelerateInterpolator(1).", trace.categories.Animation); - return easeOut; + return easeOut(); case enums.AnimationCurve.easeInOut: trace.write("Animation curve resolved to android.view.animation.AccelerateDecelerateInterpolator().", trace.categories.Animation); - return easeInOut; + return easeInOut(); case enums.AnimationCurve.linear: trace.write("Animation curve resolved to android.view.animation.LinearInterpolator().", trace.categories.Animation); - return linear; + return linear(); case enums.AnimationCurve.spring: trace.write("Animation curve resolved to android.view.animation.BounceInterpolator().", trace.categories.Animation); - return bounce; + return bounce(); case enums.AnimationCurve.ease: return (android).support.v4.view.animation.PathInterpolatorCompat.create(0.25, 0.1, 0.25, 1.0); default: diff --git a/ui/transition/slide-transition.android.ts b/ui/transition/slide-transition.android.ts index 7b67f0d7c..bfe726416 100644 --- a/ui/transition/slide-transition.android.ts +++ b/ui/transition/slide-transition.android.ts @@ -1,8 +1,9 @@ import transition = require("ui/transition"); import platform = require("platform"); +import lazy from "utils/lazy"; -var screenWidth = platform.screen.mainScreen.widthPixels; -var screenHeight = platform.screen.mainScreen.heightPixels; +var screenWidth = lazy(() => platform.screen.mainScreen.widthPixels); +var screenHeight = lazy(() => platform.screen.mainScreen.heightPixels); export class SlideTransition extends transition.Transition { private _direction: string; @@ -18,80 +19,80 @@ export class SlideTransition extends transition.Transition { case "left": switch (transitionType) { case transition.AndroidTransitionType.enter: - translationValues[0] = screenWidth; + translationValues[0] = screenWidth(); translationValues[1] = 0; break; case transition.AndroidTransitionType.exit: translationValues[0] = 0; - translationValues[1] = -screenWidth; + translationValues[1] = -screenWidth(); break; case transition.AndroidTransitionType.popEnter: - translationValues[0] = -screenWidth; + translationValues[0] = -screenWidth(); translationValues[1] = 0; break; case transition.AndroidTransitionType.popExit: translationValues[0] = 0; - translationValues[1] = screenWidth; + translationValues[1] = screenWidth(); break; } break; case "right": switch (transitionType) { case transition.AndroidTransitionType.enter: - translationValues[0] = -screenWidth; + translationValues[0] = -screenWidth(); translationValues[1] = 0; break; case transition.AndroidTransitionType.exit: translationValues[0] = 0; - translationValues[1] = screenWidth; + translationValues[1] = screenWidth(); break; case transition.AndroidTransitionType.popEnter: - translationValues[0] = screenWidth; + translationValues[0] = screenWidth(); translationValues[1] = 0; break; case transition.AndroidTransitionType.popExit: translationValues[0] = 0; - translationValues[1] = -screenWidth; + translationValues[1] = -screenWidth(); break; } break; case "top": switch (transitionType) { case transition.AndroidTransitionType.enter: - translationValues[0] = screenHeight; + translationValues[0] = screenHeight(); translationValues[1] = 0; break; case transition.AndroidTransitionType.exit: translationValues[0] = 0; - translationValues[1] = -screenHeight; + translationValues[1] = -screenHeight(); break; case transition.AndroidTransitionType.popEnter: - translationValues[0] = -screenHeight; + translationValues[0] = -screenHeight(); translationValues[1] = 0; break; case transition.AndroidTransitionType.popExit: translationValues[0] = 0; - translationValues[1] = screenHeight; + translationValues[1] = screenHeight(); break; } break; case "bottom": switch (transitionType) { case transition.AndroidTransitionType.enter: - translationValues[0] = -screenHeight; + translationValues[0] = -screenHeight(); translationValues[1] = 0; break; case transition.AndroidTransitionType.exit: translationValues[0] = 0; - translationValues[1] = screenHeight; + translationValues[1] = screenHeight(); break; case transition.AndroidTransitionType.popEnter: - translationValues[0] = screenHeight; + translationValues[0] = screenHeight(); translationValues[1] = 0; break; case transition.AndroidTransitionType.popExit: translationValues[0] = 0; - translationValues[1] = -screenHeight; + translationValues[1] = -screenHeight(); break; } break; diff --git a/ui/transition/transition.android.ts b/ui/transition/transition.android.ts index 2c090dfb9..d4f469578 100644 --- a/ui/transition/transition.android.ts +++ b/ui/transition/transition.android.ts @@ -5,9 +5,10 @@ import pageModule = require("ui/page"); import * as animationModule from "ui/animation"; import types = require("utils/types"); import trace = require("trace"); +import lazy from "utils/lazy"; -var _sdkVersion = parseInt(platform.device.sdkVersion); -var _defaultInterpolator = new android.view.animation.AccelerateDecelerateInterpolator(); +var _sdkVersion = lazy(() => parseInt(platform.device.sdkVersion)); +var _defaultInterpolator = lazy(() => new android.view.animation.AccelerateDecelerateInterpolator()); interface CompleteOptions { isBack: boolean; @@ -40,7 +41,7 @@ export function _clearBackwardTransitions(fragment: any): void { expandedFragment.enterPopExitTransition = undefined; } - if (_sdkVersion >= 21) { + if (_sdkVersion() >= 21) { var enterTransition = (fragment).getEnterTransition(); if (enterTransition) { trace.write(`Cleared Enter ${enterTransition.getClass().getSimpleName()} transition for ${fragment.getTag()}`, trace.categories.Transition); @@ -61,7 +62,7 @@ export function _clearForwardTransitions(fragment: any): void { expandedFragment.exitPopEnterTransition = undefined; } - if (_sdkVersion >= 21) { + if (_sdkVersion() >= 21) { var exitTransition = (fragment).getExitTransition(); if (exitTransition) { trace.write(`Cleared Exit ${exitTransition.getClass().getSimpleName()} transition for ${fragment.getTag()}`, trace.categories.Transition); @@ -81,7 +82,7 @@ export function _setAndroidFragmentTransitions(navigationTransition: frameModule name = navigationTransition.name.toLowerCase(); } - var useLollipopTransition = name && (name.indexOf("slide") === 0 || name === "fade" || name === "explode") && _sdkVersion >= 21; + var useLollipopTransition = name && (name.indexOf("slide") === 0 || name === "fade" || name === "explode") && _sdkVersion() >= 21; if (useLollipopTransition) { // setEnterTransition: Enter // setExitTransition: Exit @@ -229,7 +230,7 @@ function _setUpNativeTransition(navigationTransition: frameModule.NavigationTran nativeTransition.setInterpolator(interpolator); } else { - nativeTransition.setInterpolator(_defaultInterpolator); + nativeTransition.setInterpolator(_defaultInterpolator()); } } @@ -241,7 +242,7 @@ export function _onFragmentShown(fragment: any, isBack: boolean): void { trace.write(`${fragment.getTag() } has been shown when going ${isBack ? "back" : "forward"}, but there is ${transitionType} ${relevantTransition}. Will complete page addition when transition ends.`, trace.categories.Transition); expandedFragment.completePageAdditionWhenTransitionEnds = { isBack: isBack }; } - else if (_sdkVersion >= 21) { + else if (_sdkVersion() >= 21) { var nativeTransition = isBack ? (fragment).getReenterTransition() : (fragment).getEnterTransition(); if (nativeTransition) { trace.write(`${fragment.getTag() } has been shown when going ${isBack ? "back" : "forward"}, but there is ${transitionType} ${nativeTransition.getClass().getSimpleName()} transition. Will complete page addition when transition ends.`, trace.categories.Transition); @@ -262,7 +263,7 @@ export function _onFragmentHidden(fragment: any, isBack: boolean, destroyed: boo trace.write(`${fragment.getTag()} has been hidden when going ${isBack ? "back" : "forward"}, but there is ${transitionType} ${relevantTransition}. Will complete page removal when transition ends.`, trace.categories.Transition); expandedFragment.completePageRemovalWhenTransitionEnds = { isBack: isBack }; } - else if (_sdkVersion >= 21) { + else if (_sdkVersion() >= 21) { var nativeTransition = isBack ? (fragment).getReturnTransition() : (fragment).getExitTransition(); if (nativeTransition) { trace.write(`${fragment.getTag()} has been hidden when going ${isBack ? "back" : "forward"}, but there is ${transitionType} ${nativeTransition.getClass().getSimpleName()} transition. Will complete page removal when transition ends.`, trace.categories.Transition); @@ -422,7 +423,7 @@ export class Transition implements definition.Transition { this._interpolator = animation._resolveAnimationCurve(curve); } else { - this._interpolator = _defaultInterpolator; + this._interpolator = _defaultInterpolator(); } this._id = transitionId++; } diff --git a/utils/lazy.d.ts b/utils/lazy.d.ts new file mode 100644 index 000000000..d2ce49ffc --- /dev/null +++ b/utils/lazy.d.ts @@ -0,0 +1,8 @@ +declare module "utils/lazy" { + /** + * A function that evaluates the action only once. + * @param action The action to be evaluated to get the result. + * Returns the evaluated result. + */ + export default function lazy(action: () => T): () => T; +} \ No newline at end of file diff --git a/utils/lazy.ts b/utils/lazy.ts new file mode 100644 index 000000000..a1cf45dd1 --- /dev/null +++ b/utils/lazy.ts @@ -0,0 +1,4 @@ +export default function lazy(action: () => T): () => T { + let _value: T; + return () => _value || (_value = action()); +} \ No newline at end of file