mirror of
https://github.com/NativeScript/NativeScript.git
synced 2025-08-15 11:01:21 +08:00
Merge pull request #2222 from NativeScript/hardware-animations
Enable hardware acceleration for views animations in Android
This commit is contained in:
@ -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<android.animation.Animator>();
|
||||
this._propertyUpdateCallbacks = new Array<Function>();
|
||||
this._propertyResetCallbacks = new Array<Function>();
|
||||
|
||||
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 = (<any>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 = (<android.view.View>propertyAnimation.target._nativeView);
|
||||
let nativeView = <android.view.View>propertyAnimation.target._nativeView;
|
||||
let animators = new Array<android.animation.Animator>();
|
||||
let propertyUpdateCallbacks = new Array<Function>();
|
||||
let propertyResetCallbacks = new Array<Function>();
|
||||
@ -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 = <CacheLayerType>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 = <CacheLayerType>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;
|
||||
}
|
||||
}
|
||||
}
|
@ -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<string, android.graphics.drawable.Drawable>();
|
||||
|
||||
interface CacheLayerType {
|
||||
layerType: number;
|
||||
}
|
||||
|
||||
export function onBackgroundOrBorderPropertyChanged(v: view.View) {
|
||||
var nativeView = <android.view.View>v._nativeView;
|
||||
var cache = <CacheLayerType>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;
|
||||
}
|
||||
}
|
||||
|
9
tns-core-modules/utils/utils.d.ts
vendored
9
tns-core-modules/utils/utils.d.ts
vendored
@ -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
|
||||
|
||||
/**
|
||||
|
Reference in New Issue
Block a user