Remove value callback animations when they get overwritten (#1470)
Fixes #1464
diff --git a/LottieSample/src/main/kotlin/com/airbnb/lottie/samples/DynamicActivity.kt b/LottieSample/src/main/kotlin/com/airbnb/lottie/samples/DynamicActivity.kt
index 9e04ad3..8970d49 100644
--- a/LottieSample/src/main/kotlin/com/airbnb/lottie/samples/DynamicActivity.kt
+++ b/LottieSample/src/main/kotlin/com/airbnb/lottie/samples/DynamicActivity.kt
@@ -48,19 +48,18 @@
animationView.addLottieOnCompositionLoadedListener { _ ->
animationView.resolveKeyPath(KeyPath("**")).forEach {
Log.d(TAG, it.keysToString())
+ setupValueCallbacks()
}
}
animationView.setFailureListener { e ->
- Log.e(TAG, "Failed to load composition", e)
+ Log.e(TAG, "Failed to load animation!", e)
}
updateButtonText()
-
}
private fun setupValueCallbacks() {
- animationView.addValueCallback(KeyPath("LeftArmWave"),
- LottieProperty.TIME_REMAP) { frameInfo ->
+ animationView.addValueCallback(KeyPath("LeftArmWave"), LottieProperty.TIME_REMAP) { frameInfo ->
2 * speed.toFloat() * frameInfo.overallProgress
}
diff --git a/gradle.properties b/gradle.properties
index c1c627b..65698f0 100644
--- a/gradle.properties
+++ b/gradle.properties
@@ -34,3 +34,7 @@
POM_INCEPTION_YEAR=2017
android.useAndroidX=true
android.enableJetifier=true
+org.gradle.caching=true
+org.gradle.jvmargs=-Xmx4096m
+org.gradle.daemon=true
+org.gradle.parallel=true
diff --git a/lottie/src/main/java/com/airbnb/lottie/animation/content/BaseStrokeContent.java b/lottie/src/main/java/com/airbnb/lottie/animation/content/BaseStrokeContent.java
index 8a1aece..813a8aa 100644
--- a/lottie/src/main/java/com/airbnb/lottie/animation/content/BaseStrokeContent.java
+++ b/lottie/src/main/java/com/airbnb/lottie/animation/content/BaseStrokeContent.java
@@ -314,6 +314,10 @@
} else if (property == LottieProperty.STROKE_WIDTH) {
widthAnimation.setValueCallback((LottieValueCallback<Float>) callback);
} else if (property == LottieProperty.COLOR_FILTER) {
+ if (colorFilterAnimation != null) {
+ layer.removeAnimation(colorFilterAnimation);
+ }
+
if (callback == null) {
colorFilterAnimation = null;
} else {
diff --git a/lottie/src/main/java/com/airbnb/lottie/animation/content/FillContent.java b/lottie/src/main/java/com/airbnb/lottie/animation/content/FillContent.java
index 4e3b838..56420f9 100644
--- a/lottie/src/main/java/com/airbnb/lottie/animation/content/FillContent.java
+++ b/lottie/src/main/java/com/airbnb/lottie/animation/content/FillContent.java
@@ -128,6 +128,10 @@
} else if (property == LottieProperty.OPACITY) {
opacityAnimation.setValueCallback((LottieValueCallback<Integer>) callback);
} else if (property == LottieProperty.COLOR_FILTER) {
+ if (colorFilterAnimation != null) {
+ layer.removeAnimation(colorFilterAnimation);
+ }
+
if (callback == null) {
colorFilterAnimation = null;
} else {
diff --git a/lottie/src/main/java/com/airbnb/lottie/animation/content/GradientFillContent.java b/lottie/src/main/java/com/airbnb/lottie/animation/content/GradientFillContent.java
index 747c20c..869cb4e 100644
--- a/lottie/src/main/java/com/airbnb/lottie/animation/content/GradientFillContent.java
+++ b/lottie/src/main/java/com/airbnb/lottie/animation/content/GradientFillContent.java
@@ -235,6 +235,10 @@
if (property == LottieProperty.OPACITY) {
opacityAnimation.setValueCallback((LottieValueCallback<Integer>) callback);
} else if (property == LottieProperty.COLOR_FILTER) {
+ if (colorFilterAnimation != null) {
+ layer.removeAnimation(colorFilterAnimation);
+ }
+
if (callback == null) {
colorFilterAnimation = null;
} else {
@@ -244,12 +248,14 @@
layer.addAnimation(colorFilterAnimation);
}
} else if (property == LottieProperty.GRADIENT_COLOR) {
+ if (colorCallbackAnimation != null) {
+ layer.removeAnimation(colorCallbackAnimation);
+ }
+
if (callback == null) {
- if (colorCallbackAnimation != null) {
- layer.removeAnimation(colorCallbackAnimation);
- }
colorCallbackAnimation = null;
} else {
+ //noinspection rawtypes
colorCallbackAnimation = new ValueCallbackKeyframeAnimation<>(callback);
colorCallbackAnimation.addUpdateListener(this);
layer.addAnimation(colorCallbackAnimation);
diff --git a/lottie/src/main/java/com/airbnb/lottie/animation/content/GradientStrokeContent.java b/lottie/src/main/java/com/airbnb/lottie/animation/content/GradientStrokeContent.java
index ab5a29a..351171c 100644
--- a/lottie/src/main/java/com/airbnb/lottie/animation/content/GradientStrokeContent.java
+++ b/lottie/src/main/java/com/airbnb/lottie/animation/content/GradientStrokeContent.java
@@ -164,10 +164,11 @@
public <T> void addValueCallback(T property, @Nullable LottieValueCallback<T> callback) {
super.addValueCallback(property, callback);
if (property == LottieProperty.GRADIENT_COLOR) {
+ if (colorCallbackAnimation != null) {
+ layer.removeAnimation(colorCallbackAnimation);
+ }
+
if (callback == null) {
- if (colorCallbackAnimation != null) {
- layer.removeAnimation(colorCallbackAnimation);
- }
colorCallbackAnimation = null;
} else {
colorCallbackAnimation = new ValueCallbackKeyframeAnimation<>(callback);
diff --git a/lottie/src/main/java/com/airbnb/lottie/animation/content/PolystarContent.java b/lottie/src/main/java/com/airbnb/lottie/animation/content/PolystarContent.java
index 651511e..c13c63f 100644
--- a/lottie/src/main/java/com/airbnb/lottie/animation/content/PolystarContent.java
+++ b/lottie/src/main/java/com/airbnb/lottie/animation/content/PolystarContent.java
@@ -316,8 +316,7 @@
innerRadiusAnimation.setValueCallback((LottieValueCallback<Float>) callback);
} else if (property == LottieProperty.POLYSTAR_OUTER_RADIUS) {
outerRadiusAnimation.setValueCallback((LottieValueCallback<Float>) callback);
- } else if (property == LottieProperty.POLYSTAR_INNER_ROUNDEDNESS &&
- innerRoundednessAnimation != null) {
+ } else if (property == LottieProperty.POLYSTAR_INNER_ROUNDEDNESS && innerRoundednessAnimation != null) {
innerRoundednessAnimation.setValueCallback((LottieValueCallback<Float>) callback);
} else if (property == LottieProperty.POLYSTAR_OUTER_ROUNDEDNESS) {
outerRoundednessAnimation.setValueCallback((LottieValueCallback<Float>) callback);
diff --git a/lottie/src/main/java/com/airbnb/lottie/animation/content/StrokeContent.java b/lottie/src/main/java/com/airbnb/lottie/animation/content/StrokeContent.java
index 524ecb0..4e4900e 100644
--- a/lottie/src/main/java/com/airbnb/lottie/animation/content/StrokeContent.java
+++ b/lottie/src/main/java/com/airbnb/lottie/animation/content/StrokeContent.java
@@ -58,6 +58,10 @@
if (property == STROKE_COLOR) {
colorAnimation.setValueCallback((LottieValueCallback<Integer>) callback);
} else if (property == LottieProperty.COLOR_FILTER) {
+ if (colorFilterAnimation != null) {
+ layer.removeAnimation(colorFilterAnimation);
+ }
+
if (callback == null) {
colorFilterAnimation = null;
} else {
diff --git a/lottie/src/main/java/com/airbnb/lottie/model/layer/CompositionLayer.java b/lottie/src/main/java/com/airbnb/lottie/model/layer/CompositionLayer.java
index 12a126b..d782f44 100644
--- a/lottie/src/main/java/com/airbnb/lottie/model/layer/CompositionLayer.java
+++ b/lottie/src/main/java/com/airbnb/lottie/model/layer/CompositionLayer.java
@@ -201,9 +201,12 @@
if (property == LottieProperty.TIME_REMAP) {
if (callback == null) {
- timeRemapping = null;
+ if (timeRemapping != null) {
+ timeRemapping.setValueCallback(null);
+ }
} else {
timeRemapping = new ValueCallbackKeyframeAnimation<>((LottieValueCallback<Float>) callback);
+ timeRemapping.addUpdateListener(this);
addAnimation(timeRemapping);
}
}
diff --git a/lottie/src/main/java/com/airbnb/lottie/model/layer/TextLayer.java b/lottie/src/main/java/com/airbnb/lottie/model/layer/TextLayer.java
index 494a581..3a02b6b 100644
--- a/lottie/src/main/java/com/airbnb/lottie/model/layer/TextLayer.java
+++ b/lottie/src/main/java/com/airbnb/lottie/model/layer/TextLayer.java
@@ -52,13 +52,23 @@
@Nullable
private BaseKeyframeAnimation<Integer, Integer> colorAnimation;
@Nullable
+ private BaseKeyframeAnimation<Integer, Integer> colorCallbackAnimation;
+ @Nullable
private BaseKeyframeAnimation<Integer, Integer> strokeColorAnimation;
@Nullable
+ private BaseKeyframeAnimation<Integer, Integer> strokeColorCallbackAnimation;
+ @Nullable
private BaseKeyframeAnimation<Float, Float> strokeWidthAnimation;
@Nullable
+ private BaseKeyframeAnimation<Float, Float> strokeWidthCallbackAnimation;
+ @Nullable
private BaseKeyframeAnimation<Float, Float> trackingAnimation;
@Nullable
+ private BaseKeyframeAnimation<Float, Float> trackingCallbackAnimation;
+ @Nullable
private BaseKeyframeAnimation<Float, Float> textSizeAnimation;
+ @Nullable
+ private BaseKeyframeAnimation<Float, Float> textSizeCallbackAnimation;
TextLayer(LottieDrawable lottieDrawable, Layer layerModel) {
super(lottieDrawable, layerModel);
@@ -116,13 +126,17 @@
return;
}
- if (colorAnimation != null) {
+ if (colorCallbackAnimation != null) {
+ fillPaint.setColor(colorCallbackAnimation.getValue());
+ } else if (colorAnimation != null) {
fillPaint.setColor(colorAnimation.getValue());
} else {
fillPaint.setColor(documentData.color);
}
- if (strokeColorAnimation != null) {
+ if (strokeColorCallbackAnimation != null) {
+ strokePaint.setColor(strokeColorCallbackAnimation.getValue());
+ } else if (strokeColorAnimation != null) {
strokePaint.setColor(strokeColorAnimation.getValue());
} else {
strokePaint.setColor(documentData.strokeColor);
@@ -132,7 +146,9 @@
fillPaint.setAlpha(alpha);
strokePaint.setAlpha(alpha);
- if (strokeWidthAnimation != null) {
+ if (strokeWidthCallbackAnimation != null) {
+ strokePaint.setStrokeWidth(strokeWidthCallbackAnimation.getValue());
+ } else if (strokeWidthAnimation != null) {
strokePaint.setStrokeWidth(strokeWidthAnimation.getValue());
} else {
float parentScale = Utils.getScale(parentMatrix);
@@ -150,7 +166,14 @@
private void drawTextGlyphs(
DocumentData documentData, Matrix parentMatrix, Font font, Canvas canvas) {
- float textSize = textSizeAnimation == null ? documentData.size : textSizeAnimation.getValue();
+ float textSize;
+ if (textSizeCallbackAnimation != null) {
+ textSize = textSizeCallbackAnimation.getValue();
+ } else if (textSizeAnimation != null) {
+ textSize = textSizeAnimation.getValue();
+ } else {
+ textSize = documentData.size;
+ }
float fontScale = textSize / 100f;
float parentScale = Utils.getScale(parentMatrix);
@@ -199,7 +222,9 @@
float tx = (float) character.getWidth() * fontScale * Utils.dpScale() * parentScale;
// Add tracking
float tracking = documentData.tracking / 10f;
- if (trackingAnimation != null) {
+ if (trackingCallbackAnimation != null) {
+ tracking += trackingCallbackAnimation.getValue();
+ } else if (trackingAnimation != null) {
tracking += trackingAnimation.getValue();
}
tx += tracking * parentScale;
@@ -220,7 +245,14 @@
text = textDelegate.getTextInternal(text);
}
fillPaint.setTypeface(typeface);
- float textSize = textSizeAnimation == null ? documentData.size : textSizeAnimation.getValue();
+ float textSize;
+ if (textSizeCallbackAnimation != null) {
+ textSize = textSizeCallbackAnimation.getValue();
+ } else if (textSizeAnimation != null) {
+ textSize = textSizeAnimation.getValue();
+ } else {
+ textSize = documentData.size;
+ }
fillPaint.setTextSize(textSize * Utils.dpScale());
strokePaint.setTypeface(fillPaint.getTypeface());
strokePaint.setTextSize(fillPaint.getTextSize());
@@ -268,7 +300,9 @@
float charWidth = fillPaint.measureText(charString, 0, 1);
// Add tracking
float tracking = documentData.tracking / 10f;
- if (trackingAnimation != null) {
+ if (trackingCallbackAnimation != null) {
+ tracking += trackingCallbackAnimation.getValue();
+ } else if (trackingAnimation != null) {
tracking += trackingAnimation.getValue();
}
float tx = charWidth + tracking * parentScale;
@@ -417,75 +451,64 @@
public <T> void addValueCallback(T property, @Nullable LottieValueCallback<T> callback) {
super.addValueCallback(property, callback);
if (property == LottieProperty.COLOR) {
- if (colorAnimation != null) {
- colorAnimation.setValueCallback((LottieValueCallback<Integer>) callback);
+ if (colorCallbackAnimation != null) {
+ removeAnimation(colorCallbackAnimation);
+ }
+
+ if (callback == null) {
+ colorCallbackAnimation = null;
} else {
- if (callback == null) {
- if (colorAnimation != null) {
- removeAnimation(colorAnimation);
- }
- colorAnimation = null;
- } else {
- colorAnimation = new ValueCallbackKeyframeAnimation<>((LottieValueCallback<Integer>) callback);
- colorAnimation.addUpdateListener(this);
- addAnimation(colorAnimation);
- }
+ colorCallbackAnimation = new ValueCallbackKeyframeAnimation<>((LottieValueCallback<Integer>) callback);
+ colorCallbackAnimation.addUpdateListener(this);
+ addAnimation(colorCallbackAnimation);
}
} else if (property == LottieProperty.STROKE_COLOR) {
- if (strokeColorAnimation != null) {
- strokeColorAnimation.setValueCallback((LottieValueCallback<Integer>) callback);
+ if (strokeColorCallbackAnimation != null) {
+ removeAnimation(strokeColorCallbackAnimation);
+ }
+
+ if (callback == null) {
+ strokeColorCallbackAnimation = null;
} else {
- if (callback == null) {
- if (strokeColorAnimation != null) {
- removeAnimation(strokeColorAnimation);
- }
- strokeColorAnimation = null;
- } else {
- strokeColorAnimation = new ValueCallbackKeyframeAnimation<>((LottieValueCallback<Integer>) callback);
- strokeColorAnimation.addUpdateListener(this);
- addAnimation(strokeColorAnimation);
- }
+ strokeColorCallbackAnimation = new ValueCallbackKeyframeAnimation<>((LottieValueCallback<Integer>) callback);
+ strokeColorCallbackAnimation.addUpdateListener(this);
+ addAnimation(strokeColorCallbackAnimation);
}
} else if (property == LottieProperty.STROKE_WIDTH) {
- if (strokeWidthAnimation != null) {
- strokeWidthAnimation.setValueCallback((LottieValueCallback<Float>) callback);
+ if (strokeWidthCallbackAnimation != null) {
+ removeAnimation(strokeWidthCallbackAnimation);
+ }
+
+ if (callback == null) {
+ strokeWidthCallbackAnimation = null;
} else {
- if (callback == null) {
- if (strokeWidthAnimation != null) {
- removeAnimation(strokeWidthAnimation);
- }
- strokeWidthAnimation = null;
- } else {
- strokeWidthAnimation = new ValueCallbackKeyframeAnimation<>((LottieValueCallback<Float>) callback);
- strokeWidthAnimation.addUpdateListener(this);
- addAnimation(strokeWidthAnimation);
- }
+ strokeWidthCallbackAnimation = new ValueCallbackKeyframeAnimation<>((LottieValueCallback<Float>) callback);
+ strokeWidthCallbackAnimation.addUpdateListener(this);
+ addAnimation(strokeWidthCallbackAnimation);
}
} else if (property == LottieProperty.TEXT_TRACKING) {
- if (trackingAnimation != null) {
- trackingAnimation.setValueCallback((LottieValueCallback<Float>) callback);
+ if (trackingCallbackAnimation != null) {
+ removeAnimation(trackingCallbackAnimation);
+ }
+
+ if (callback == null) {
+ trackingCallbackAnimation = null;
} else {
- if (callback == null) {
- if (trackingAnimation != null) {
- removeAnimation(trackingAnimation);
- }
- trackingAnimation = null;
- } else {
- trackingAnimation = new ValueCallbackKeyframeAnimation<>((LottieValueCallback<Float>) callback);
- trackingAnimation.addUpdateListener(this);
- addAnimation(trackingAnimation);
- }
+ trackingCallbackAnimation = new ValueCallbackKeyframeAnimation<>((LottieValueCallback<Float>) callback);
+ trackingCallbackAnimation.addUpdateListener(this);
+ addAnimation(trackingCallbackAnimation);
}
} else if (property == LottieProperty.TEXT_SIZE) {
+ if (textSizeCallbackAnimation != null) {
+ removeAnimation(textSizeCallbackAnimation);
+ }
+
if (callback == null) {
- if (textSizeAnimation != null) {
- removeAnimation(textSizeAnimation);
- }
- textSizeAnimation = null;
+ textSizeCallbackAnimation = null;
} else {
- textSizeAnimation = new ValueCallbackKeyframeAnimation<>((LottieValueCallback<Float>) callback);
- textSizeAnimation.addUpdateListener(this);
- addAnimation(textSizeAnimation);
+ textSizeCallbackAnimation = new ValueCallbackKeyframeAnimation<>((LottieValueCallback<Float>) callback);
+ textSizeCallbackAnimation.addUpdateListener(this);
+ addAnimation(textSizeCallbackAnimation);
}
}
}