mirror of
https://github.com/NativeScript/NativeScript.git
synced 2025-11-05 13:26:48 +08:00
fix(android-animations): reuse animatorSet to prevent high memory usage (#6930)
This commit is contained in:
committed by
GitHub
parent
09fa0856b8
commit
7236d32a24
@@ -9,6 +9,7 @@ import {
|
|||||||
} from "../styling/style-properties";
|
} from "../styling/style-properties";
|
||||||
|
|
||||||
import { layout } from "../../utils/utils";
|
import { layout } from "../../utils/utils";
|
||||||
|
import { device } from "../../platform";
|
||||||
import lazy from "../../utils/lazy";
|
import lazy from "../../utils/lazy";
|
||||||
|
|
||||||
export * from "./animation-common";
|
export * from "./animation-common";
|
||||||
@@ -92,6 +93,7 @@ export class Animation extends AnimationBase {
|
|||||||
private _propertyResetCallbacks: Array<Function>;
|
private _propertyResetCallbacks: Array<Function>;
|
||||||
private _valueSource: "animation" | "keyframe";
|
private _valueSource: "animation" | "keyframe";
|
||||||
private _target: View;
|
private _target: View;
|
||||||
|
private _resetOnFinish: boolean = true;
|
||||||
|
|
||||||
constructor(animationDefinitions: Array<AnimationDefinitionInternal>, playSequentially?: boolean) {
|
constructor(animationDefinitions: Array<AnimationDefinitionInternal>, playSequentially?: boolean) {
|
||||||
super(animationDefinitions, playSequentially);
|
super(animationDefinitions, playSequentially);
|
||||||
@@ -134,12 +136,18 @@ export class Animation extends AnimationBase {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
public play(): AnimationPromise {
|
public play(resetOnFinish?: boolean): AnimationPromise {
|
||||||
|
if (resetOnFinish !== undefined) {
|
||||||
|
this._resetOnFinish = resetOnFinish;
|
||||||
|
}
|
||||||
|
|
||||||
if (this.isPlaying) {
|
if (this.isPlaying) {
|
||||||
return this._rejectAlreadyPlaying();
|
return this._rejectAlreadyPlaying();
|
||||||
}
|
}
|
||||||
|
|
||||||
let animationFinishedPromise = super.play();
|
if (this._animatorSet) {
|
||||||
|
return this._play();
|
||||||
|
}
|
||||||
|
|
||||||
this._animators = new Array<android.animation.Animator>();
|
this._animators = new Array<android.animation.Animator>();
|
||||||
this._propertyUpdateCallbacks = new Array<Function>();
|
this._propertyUpdateCallbacks = new Array<Function>();
|
||||||
@@ -156,21 +164,8 @@ export class Animation extends AnimationBase {
|
|||||||
|
|
||||||
this._animatorSet = new android.animation.AnimatorSet();
|
this._animatorSet = new android.animation.AnimatorSet();
|
||||||
this._animatorSet.addListener(this._animatorListener);
|
this._animatorSet.addListener(this._animatorListener);
|
||||||
if (this._animators.length > 0) {
|
|
||||||
if (this._playSequentially) {
|
|
||||||
this._animatorSet.playSequentially(this._nativeAnimatorsArray);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
this._animatorSet.playTogether(this._nativeAnimatorsArray);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (traceEnabled()) {
|
return this._play();
|
||||||
traceWrite("Starting " + this._nativeAnimatorsArray.length + " animations " + (this._playSequentially ? "sequentially." : "together."), traceCategories.Animation);
|
|
||||||
}
|
|
||||||
this._animatorSet.setupStartValues();
|
|
||||||
this._animatorSet.start();
|
|
||||||
return animationFinishedPromise;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public cancel(): void {
|
public cancel(): void {
|
||||||
@@ -188,6 +183,33 @@ export class Animation extends AnimationBase {
|
|||||||
return _resolveAnimationCurve(curve);
|
return _resolveAnimationCurve(curve);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private _play(): AnimationPromise {
|
||||||
|
const animationFinishedPromise = super.play();
|
||||||
|
|
||||||
|
if (device.sdkVersion <= "23") {
|
||||||
|
this._animatorSet = new android.animation.AnimatorSet();
|
||||||
|
this._animatorSet.addListener(this._animatorListener);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (this._animators.length > 0) {
|
||||||
|
if (this._playSequentially) {
|
||||||
|
this._animatorSet.playSequentially(this._nativeAnimatorsArray);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
this._animatorSet.playTogether(this._nativeAnimatorsArray);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (traceEnabled()) {
|
||||||
|
traceWrite("Starting " + this._nativeAnimatorsArray.length + " animations " + (this._playSequentially ? "sequentially." : "together."), traceCategories.Animation);
|
||||||
|
}
|
||||||
|
|
||||||
|
this._animatorSet.setupStartValues();
|
||||||
|
this._animatorSet.start();
|
||||||
|
|
||||||
|
return animationFinishedPromise;
|
||||||
|
}
|
||||||
|
|
||||||
private _onAndroidAnimationEnd() { // tslint:disable-line
|
private _onAndroidAnimationEnd() { // tslint:disable-line
|
||||||
if (!this.isPlaying) {
|
if (!this.isPlaying) {
|
||||||
// It has been cancelled
|
// It has been cancelled
|
||||||
@@ -197,7 +219,7 @@ export class Animation extends AnimationBase {
|
|||||||
this._propertyUpdateCallbacks.forEach(v => v());
|
this._propertyUpdateCallbacks.forEach(v => v());
|
||||||
this._resolveAnimationFinishedPromise();
|
this._resolveAnimationFinishedPromise();
|
||||||
|
|
||||||
if (this._target) {
|
if (this._resetOnFinish && this._target) {
|
||||||
this._target._removeAnimation(this);
|
this._target._removeAnimation(this);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
2
tns-core-modules/ui/animation/animation.d.ts
vendored
2
tns-core-modules/ui/animation/animation.d.ts
vendored
@@ -126,7 +126,7 @@ export type AnimationPromise = Promise<void> & Cancelable;
|
|||||||
*/
|
*/
|
||||||
export class Animation {
|
export class Animation {
|
||||||
constructor(animationDefinitions: Array<AnimationDefinition>, playSequentially?: boolean);
|
constructor(animationDefinitions: Array<AnimationDefinition>, playSequentially?: boolean);
|
||||||
public play: () => AnimationPromise;
|
public play: (resetOnFinish?: boolean) => AnimationPromise;
|
||||||
public cancel: () => void;
|
public cancel: () => void;
|
||||||
public isPlaying: boolean;
|
public isPlaying: boolean;
|
||||||
public _resolveAnimationCurve(curve: any): any;
|
public _resolveAnimationCurve(curve: any): any;
|
||||||
|
|||||||
@@ -243,8 +243,10 @@ export class KeyframeAnimation implements KeyframeAnimationDefinition {
|
|||||||
this._nativeAnimations.push(animation);
|
this._nativeAnimations.push(animation);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const isLastIteration = iterations - 1 <= 0;
|
||||||
|
|
||||||
// Catch the animation cancel to prevent unhandled promise rejection warnings
|
// Catch the animation cancel to prevent unhandled promise rejection warnings
|
||||||
animation.play().then(() => {
|
animation.play(isLastIteration).then(() => {
|
||||||
this.animate(view, index + 1, iterations);
|
this.animate(view, index + 1, iterations);
|
||||||
}, (error: any) => {
|
}, (error: any) => {
|
||||||
traceWrite(typeof error === "string" ? error : error.message, traceCategories.Animation, traceType.warn);
|
traceWrite(typeof error === "string" ? error : error.message, traceCategories.Animation, traceType.warn);
|
||||||
|
|||||||
Reference in New Issue
Block a user