Skip to content

Commit e3a8fce

Browse files
authored
Fix rounded corner animations when the underlying shape doesn't animate (#2567)
Previously, if there was a rounded corners animation but no animation on the shape, the shape would never be marked as dirty and would keep returning the cached value. #2561
1 parent 39796b3 commit e3a8fce

File tree

7 files changed

+24
-4
lines changed

7 files changed

+24
-4
lines changed

.gitignore

+2-1
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,8 @@
1111
.idea/**/usage.statistics.xml
1212
.idea/**/dictionaries
1313
.idea/**/shelf
14-
.idea/runConfigurations
14+
.idea/runConfigurations.xml
15+
.idea/caches
1516

1617
# Generated files
1718
.idea/**/contentModel.xml

lottie/src/main/java/com/airbnb/lottie/animation/content/RoundedCornersContent.java

+4
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,10 @@ public BaseKeyframeAnimation<Float, Float> getRoundedCorners() {
5151
return roundedCorners;
5252
}
5353

54+
@Override public void addUpdateListener(BaseKeyframeAnimation.AnimationListener listener) {
55+
roundedCorners.addUpdateListener(listener);
56+
}
57+
5458
/**
5559
* Rounded corner algorithm:
5660
* Iterate through each vertex.

lottie/src/main/java/com/airbnb/lottie/animation/content/ShapeContent.java

+1
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,7 @@ private void invalidate() {
6262
if (shapeModifierContents == null) {
6363
shapeModifierContents = new ArrayList<>();
6464
}
65+
((ShapeModifierContent) content).addUpdateListener(this);
6566
shapeModifierContents.add((ShapeModifierContent) content);
6667
}
6768
}
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,9 @@
11
package com.airbnb.lottie.animation.content;
22

3+
import com.airbnb.lottie.animation.keyframe.BaseKeyframeAnimation;
34
import com.airbnb.lottie.model.content.ShapeData;
45

56
public interface ShapeModifierContent extends Content {
7+
void addUpdateListener(BaseKeyframeAnimation.AnimationListener listener);
68
ShapeData modifyShape(ShapeData shapeData);
79
}

lottie/src/main/java/com/airbnb/lottie/animation/keyframe/BaseKeyframeAnimation.java

+5-1
Original file line numberDiff line numberDiff line change
@@ -158,7 +158,7 @@ public A getValue() {
158158
A value;
159159

160160
float linearProgress = getLinearCurrentKeyframeProgress();
161-
if (valueCallback == null && keyframesWrapper.isCachedValueEnabled(linearProgress)) {
161+
if (valueCallback == null && keyframesWrapper.isCachedValueEnabled(linearProgress) && !skipCache()) {
162162
return cachedGetValue;
163163
}
164164
final Keyframe<K> keyframe = getCurrentKeyframe();
@@ -176,6 +176,10 @@ public A getValue() {
176176
return value;
177177
}
178178

179+
protected boolean skipCache() {
180+
return false;
181+
}
182+
179183
public float getProgress() {
180184
return progress;
181185
}

lottie/src/main/java/com/airbnb/lottie/animation/keyframe/ShapeKeyframeAnimation.java

+9-2
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,7 @@
11
package com.airbnb.lottie.animation.keyframe;
22

33
import android.graphics.Path;
4-
54
import androidx.annotation.Nullable;
6-
75
import com.airbnb.lottie.animation.content.ShapeModifierContent;
86
import com.airbnb.lottie.model.content.ShapeData;
97
import com.airbnb.lottie.utils.MiscUtils;
@@ -23,6 +21,15 @@ public ShapeKeyframeAnimation(List<Keyframe<ShapeData>> keyframes) {
2321
super(keyframes);
2422
}
2523

24+
@Override protected boolean skipCache() {
25+
// If there are shape modifiers but no animation on the shape itself, the shape animation
26+
// will think nothing changed and will keep returning its cached value.
27+
// Ideally, we would have a dirty flag rather than permanently disabling the cache
28+
// when there is a modifier. However, because shape modifiers can be reused across multiple
29+
// other contents, it isn't trivial to know when to flip dirty to false.
30+
return shapeModifiers != null && !shapeModifiers.isEmpty();
31+
}
32+
2633
@Override public Path getValue(Keyframe<ShapeData> keyframe, float keyframeProgress) {
2734
ShapeData startShapeData = keyframe.startValue;
2835
ShapeData endShapeData = keyframe.endValue;
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
{"v":"5.12.2","fr":30,"ip":0,"op":30,"w":500,"h":500,"nm":"closedpath","ddd":0,"assets":[],"layers":[{"ddd":0,"ind":1,"ty":4,"nm":"closed","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[350,272,0],"ix":2,"l":2},"a":{"a":0,"k":[0,0,0],"ix":1,"l":2},"s":{"a":0,"k":[100,100,100],"ix":6,"l":2}},"ao":0,"shapes":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[-125,-97],[-215,-17],[-135,52],[-56,-19]],"c":true},"ix":2},"nm":"路径 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"rd","nm":"圆角 1","r":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":0,"s":[0]},{"t":29,"s":[46]}],"ix":1},"ix":2,"mn":"ADBE Vector Filter - RC","hd":false},{"ty":"st","c":{"a":0,"k":[0.004289215896,0.004289215896,0.004289215896,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":12,"ix":5},"lc":1,"lj":1,"ml":4,"bm":0,"nm":"描边 1","mn":"ADBE Vector Graphic - Stroke","hd":false}],"ip":0,"op":40,"st":0,"ct":1,"bm":0},{"ddd":0,"ind":2,"ty":1,"nm":"bg","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[250,250,0],"ix":2,"l":2},"a":{"a":0,"k":[250,250,0],"ix":1,"l":2},"s":{"a":0,"k":[100,100,100],"ix":6,"l":2}},"ao":0,"sw":500,"sh":500,"sc":"#ffffff","ip":0,"op":30,"st":0,"bm":0}],"markers":[],"props":{}}

0 commit comments

Comments
 (0)