diff --git a/tns-core-modules/ui/animation/animation.android.ts b/tns-core-modules/ui/animation/animation.android.ts index 52829f801..58cc98df1 100644 --- a/tns-core-modules/ui/animation/animation.android.ts +++ b/tns-core-modules/ui/animation/animation.android.ts @@ -7,6 +7,7 @@ import types = require("utils/types"); import enums = require("ui/enums"); import styleModule = require("ui/styling/style"); import lazy from "utils/lazy"; +import { CacheLayerType } from "utils/utils"; global.moduleMerge(common, exports); @@ -41,29 +42,22 @@ export class Animation extends common.Animation implements definition.Animation public play(): definition.AnimationPromise { let animationFinishedPromise = super.play(); - let i: number; - let length: number; - this._animators = new Array(); this._propertyUpdateCallbacks = new Array(); this._propertyResetCallbacks = new Array(); - i = 0; - length = this._propertyAnimations.length; - for (; i < length; i++) { + for (let i = 0, length = this._propertyAnimations.length; i < length; i++) { this._createAnimators(this._propertyAnimations[i]); } this._nativeAnimatorsArray = (Array).create(android.animation.Animator, this._animators.length); - i = 0; - length = this._animators.length; - for (; i < length; i++) { + for (let i = 0, length = this._animators.length; i < length; i++) { this._nativeAnimatorsArray[i] = this._animators[i]; } this._animatorSet = new android.animation.AnimatorSet(); this._animatorSet.addListener(this._animatorListener); - if (length > 0) { + if (this._animators.length > 0) { if (this._playSequentially) { this._animatorSet.playSequentially(this._nativeAnimatorsArray); } @@ -72,6 +66,8 @@ export class Animation extends common.Animation implements definition.Animation } } + this._enableHardwareAcceleration(); + if (trace.enabled) { trace.write("Starting " + this._nativeAnimatorsArray.length + " animations " + (this._playSequentially ? "sequentially." : "together."), trace.categories.Animation); } @@ -79,7 +75,7 @@ export class Animation extends common.Animation implements definition.Animation this._animatorSet.start(); return animationFinishedPromise; } - + public cancel(): void { super.cancel(); if (trace.enabled) { @@ -133,6 +129,7 @@ export class Animation extends common.Animation implements definition.Animation for (; i < length; i++) { this._propertyUpdateCallbacks[i](); } + this._disableHardwareAcceleration(); this._resolveAnimationFinishedPromise(); } @@ -142,11 +139,11 @@ export class Animation extends common.Animation implements definition.Animation for (; i < length; i++) { this._propertyResetCallbacks[i](); } + this._disableHardwareAcceleration(); this._rejectAnimationFinishedPromise(); } private _createAnimators(propertyAnimation: common.PropertyAnimation): void { - if (!propertyAnimation.target._nativeView) { return; } @@ -168,7 +165,7 @@ export class Animation extends common.Animation implements definition.Animation } let nativeArray; - let nativeView: android.view.View = (propertyAnimation.target._nativeView); + let nativeView = propertyAnimation.target._nativeView; let animators = new Array(); let propertyUpdateCallbacks = new Array(); let propertyResetCallbacks = new Array(); @@ -375,6 +372,27 @@ export class Animation extends common.Animation implements definition.Animation private static _getAndroidRepeatCount(iterations: number): number { return (iterations === Number.POSITIVE_INFINITY) ? android.view.animation.Animation.INFINITE : iterations - 1; } + + private _enableHardwareAcceleration() { + for (let i = 0, length = this._propertyAnimations.length; i < length; i++) { + let cache = this._propertyAnimations[i].target._nativeView; + let layerType = cache.getLayerType(); + if (layerType !== android.view.View.LAYER_TYPE_HARDWARE) { + cache.layerType = layerType; + cache.setLayerType(android.view.View.LAYER_TYPE_HARDWARE, null); + } + } + } + + private _disableHardwareAcceleration() { + for (let i = 0, length = this._propertyAnimations.length; i < length; i++) { + let cache = this._propertyAnimations[i].target._nativeView; + if (cache.layerType !== undefined) { + cache.setLayerType(cache.layerType, null); + cache.layerType = undefined; + } + } + } } let easeIn = lazy(() => new android.view.animation.AccelerateInterpolator(1)); @@ -422,4 +440,4 @@ export function _resolveAnimationCurve(curve: any): any { } return curve; } -} +} \ No newline at end of file diff --git a/tns-core-modules/ui/styling/background.android.ts b/tns-core-modules/ui/styling/background.android.ts index d7e57b7f6..e31168305 100644 --- a/tns-core-modules/ui/styling/background.android.ts +++ b/tns-core-modules/ui/styling/background.android.ts @@ -5,6 +5,7 @@ import view = require("ui/core/view"); import types = require("utils/types"); import * as styleModule from "./style"; import * as buttonModule from "ui/button"; +import { CacheLayerType } from "utils/utils"; //@private declare module "ui/styling/background" { @@ -238,10 +239,6 @@ export module ad { var _defaultBackgrounds = new Map(); - interface CacheLayerType { - layerType: number; - } - export function onBackgroundOrBorderPropertyChanged(v: view.View) { var nativeView = v._nativeView; var cache = v._nativeView; @@ -266,8 +263,8 @@ export module ad { let backgroundColor = bkg.backgroundColor = v.style._getValue(style.backgroundColorProperty).android; bkg.setColorFilter(backgroundColor, android.graphics.PorterDuff.Mode.SRC_IN); bkg.backgroundColor = backgroundColor; - } else if (v.borderWidth !== 0 || v.borderRadius !== 0 || !backgroundValue.isEmpty() || clipPathValue) { - + } + else if (v.borderWidth || v.borderRadius || clipPathValue || !backgroundValue.isEmpty()) { if (!(bkg instanceof BorderDrawableClass)) { bkg = new BorderDrawableClass(); let viewClass = types.getClass(v); @@ -284,11 +281,11 @@ export module ad { bkg.background = backgroundValue; bkg.clipPath = clipPathValue; - if ((v.borderWidth !== 0 || v.borderRadius !== 0 || clipPathValue) && getSDK() < 18) { + if ((v.borderWidth || v.borderRadius || clipPathValue) && getSDK() < 18) { // Switch to software because of unsupported canvas methods if hardware acceleration is on: // http://developer.android.com/guide/topics/graphics/hardware-accel.html - cache.layerType = nativeView.getLayerType(); - nativeView.setLayerType(android.view.View.LAYER_TYPE_SOFTWARE, null); + cache.layerType = cache.getLayerType(); + cache.setLayerType(android.view.View.LAYER_TYPE_SOFTWARE, null); } } else { @@ -305,8 +302,7 @@ export module ad { } if (cache.layerType !== undefined) { - // Reset layer type - nativeView.setLayerType(cache.layerType, null); + cache.setLayerType(cache.layerType, null); cache.layerType = undefined; } } diff --git a/tns-core-modules/utils/utils.d.ts b/tns-core-modules/utils/utils.d.ts index 72889d093..a2c83fbd0 100644 --- a/tns-core-modules/utils/utils.d.ts +++ b/tns-core-modules/utils/utils.d.ts @@ -10,6 +10,15 @@ interface Owned { owner: any; } + + /** + * Used to cache and restore Android views' layer type, i.e. android.view.View.getLayerType and android.view.View.setLayerType. + */ + interface CacheLayerType { + layerType: number; + setLayerType(layerType: number, paint: any): void; + getLayerType(): number; + } //@endprivate /**