Add an option to enable merge paths with a disclaimer.
Fixes #16
diff --git a/LottieSample/src/main/res/layout/fragment_animation.xml b/LottieSample/src/main/res/layout/fragment_animation.xml
index ea92e60..e0bdba1 100644
--- a/LottieSample/src/main/res/layout/fragment_animation.xml
+++ b/LottieSample/src/main/res/layout/fragment_animation.xml
@@ -32,7 +32,8 @@
android:layout_height="wrap_content"
android:layout_gravity="center"
android:background="@drawable/outline"
- android:duplicateParentState="true"/>
+ android:duplicateParentState="true"
+ app:lottie_enableMergePathsForKitKatAndAbove="true"/>
<LinearLayout
android:id="@+id/instructions"
diff --git a/lottie/src/main/java/com/airbnb/lottie/ContentGroup.java b/lottie/src/main/java/com/airbnb/lottie/ContentGroup.java
index b08748f..a16c04c 100644
--- a/lottie/src/main/java/com/airbnb/lottie/ContentGroup.java
+++ b/lottie/src/main/java/com/airbnb/lottie/ContentGroup.java
@@ -4,6 +4,7 @@
import android.graphics.Matrix;
import android.graphics.Path;
import android.support.annotation.Nullable;
+import android.util.Log;
import java.util.ArrayList;
import java.util.Iterator;
@@ -11,6 +12,7 @@
class ContentGroup implements DrawingContent, PathContent,
BaseKeyframeAnimation.AnimationListener {
+ private static final String TAG = ContentGroup.class.getSimpleName();
private final Matrix matrix = new Matrix();
private final Path path = new Path();
@@ -56,8 +58,11 @@
contents.add(new TrimPathContent(layer, (ShapeTrimPath) item));
} else //noinspection StatementWithEmptyBody
if (item instanceof MergePaths) {
- // Merge paths are not ready yet.
- // contents.add(new MergePathsContent((MergePaths) item));
+ if (lottieDrawable.enableMergePathsForKitKatAndAbove()) {
+ contents.add(new MergePathsContent((MergePaths) item));
+ } else {
+ Log.w(TAG, "Animation contains merge paths but they are disabled.");
+ }
}
}
diff --git a/lottie/src/main/java/com/airbnb/lottie/LottieAnimationView.java b/lottie/src/main/java/com/airbnb/lottie/LottieAnimationView.java
index 51e0e49..b117e9e 100644
--- a/lottie/src/main/java/com/airbnb/lottie/LottieAnimationView.java
+++ b/lottie/src/main/java/com/airbnb/lottie/LottieAnimationView.java
@@ -103,6 +103,8 @@
lottieDrawable.loop(ta.getBoolean(R.styleable.LottieAnimationView_lottie_loop, false));
setImageAssetsFolder(ta.getString(R.styleable.LottieAnimationView_lottie_imageAssetsFolder));
setProgress(ta.getFloat(R.styleable.LottieAnimationView_lottie_progress, 0));
+ enableMergePathsForKitKatAndAbove(ta.getBoolean(
+ R.styleable.LottieAnimationView_lottie_enableMergePathsForKitKatAndAbove, false));
int cacheStrategy = ta.getInt(
R.styleable.LottieAnimationView_lottie_cacheStrategy,
CacheStrategy.None.ordinal());
@@ -192,6 +194,18 @@
}
/**
+ * Enable this to get merge path support for devices running KitKat (19) and above.
+ *
+ * Merge paths currently don't work if the the operand shape is entirely contained within the
+ * first shape. If you need to cut out one shape from another shape, use an even-odd fill type
+ * instead of using merge paths.
+ */
+ @SuppressWarnings({"WeakerAccess", "Unused"})
+ public void enableMergePathsForKitKatAndAbove(boolean enable) {
+ lottieDrawable.enableMergePathsForKitKatAndAbove(enable);
+ }
+
+ /**
* Enable hardware acceleration for this view.
* READ THIS BEFORE ENABLING HARDWARE ACCELERATION:
* 1) Test your animation on the minimum API level you support. Some drawing features such as
@@ -203,7 +217,7 @@
* potentially break hardware rendering with bugs in their SKIA engine. Lottie cannot do
* anything about that.
*/
- @SuppressWarnings("WeakerAccess") public void useExperimentalHardwareAcceleration() {
+ @SuppressWarnings({"WeakerAccess", "unused"}) public void useExperimentalHardwareAcceleration() {
setLayerType(LAYER_TYPE_HARDWARE, null);
}
diff --git a/lottie/src/main/java/com/airbnb/lottie/LottieDrawable.java b/lottie/src/main/java/com/airbnb/lottie/LottieDrawable.java
index 839d9e0..6375d1a 100644
--- a/lottie/src/main/java/com/airbnb/lottie/LottieDrawable.java
+++ b/lottie/src/main/java/com/airbnb/lottie/LottieDrawable.java
@@ -9,10 +9,12 @@
import android.graphics.Matrix;
import android.graphics.PixelFormat;
import android.graphics.drawable.Drawable;
+import android.os.Build;
import android.support.annotation.FloatRange;
import android.support.annotation.IntRange;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
+import android.util.Log;
import android.view.View;
import android.view.animation.LinearInterpolator;
@@ -26,6 +28,7 @@
* of compositions.
*/
public class LottieDrawable extends Drawable implements Drawable.Callback {
+ private static final String TAG = LottieDrawable.class.getSimpleName();
private final Matrix matrix = new Matrix();
private LottieComposition composition;
private final ValueAnimator animator = ValueAnimator.ofFloat(0f, 1f);
@@ -39,6 +42,7 @@
private boolean playAnimationWhenCompositionAdded;
private boolean reverseAnimationWhenCompositionAdded;
private boolean systemAnimationsAreDisabled;
+ private boolean enableMergePaths;
@Nullable private CompositionLayer compositionLayer;
private int alpha = 255;
@@ -71,6 +75,28 @@
return compositionLayer != null && compositionLayer.hasMatte();
}
+ boolean enableMergePathsForKitKatAndAbove() {
+ return enableMergePaths;
+ }
+
+ /**
+ * Enable this to get merge path support for devices running KitKat (19) and above.
+ *
+ * Merge paths currently don't work if the the operand shape is entirely contained within the
+ * first shape. If you need to cut out one shape from another shape, use an even-odd fill type
+ * instead of using merge paths.
+ */
+ @SuppressWarnings("WeakerAccess") public void enableMergePathsForKitKatAndAbove(boolean enable) {
+ if (Build.VERSION.SDK_INT < Build.VERSION_CODES.KITKAT) {
+ Log.w(TAG, "Merge paths are not supported pre-Kit Kat.");
+ return;
+ }
+ enableMergePaths = enable;
+ if (composition != null) {
+ buildCompositionLayer();
+ }
+ }
+
/**
* If you use image assets, you must explicitly specify the folder in assets/ in which they are
* located because bodymovin uses the name filenames across all compositions (img_#).
@@ -122,8 +148,7 @@
setSpeed(speed);
setScale(1f);
updateBounds();
- compositionLayer = new CompositionLayer(
- this, Layer.Factory.newInstance(composition), composition.getLayers(), composition);
+ buildCompositionLayer();
setProgress(progress);
if (playAnimationWhenCompositionAdded) {
@@ -138,6 +163,11 @@
return true;
}
+ private void buildCompositionLayer() {
+ compositionLayer = new CompositionLayer(
+ this, Layer.Factory.newInstance(composition), composition.getLayers(), composition);
+ }
+
private void clearComposition() {
recycleBitmaps();
compositionLayer = null;
diff --git a/lottie/src/main/java/com/airbnb/lottie/MergePathsContent.java b/lottie/src/main/java/com/airbnb/lottie/MergePathsContent.java
index 1c12b9e..4214de8 100644
--- a/lottie/src/main/java/com/airbnb/lottie/MergePathsContent.java
+++ b/lottie/src/main/java/com/airbnb/lottie/MergePathsContent.java
@@ -7,6 +7,7 @@
import java.util.ArrayList;
import java.util.List;
+@TargetApi(Build.VERSION_CODES.KITKAT)
class MergePathsContent implements PathContent {
private final Path firstPath = new Path();
private final Path remainderPath = new Path();
@@ -16,6 +17,9 @@
private final MergePaths mergePaths;
MergePathsContent(MergePaths mergePaths) {
+ if (Build.VERSION.SDK_INT < Build.VERSION_CODES.KITKAT) {
+ throw new IllegalStateException("Merge paths are not supported pre-KitKat.");
+ }
this.mergePaths = mergePaths;
}
@@ -34,28 +38,9 @@
@Override public Path getPath() {
path.reset();
- if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
- mergePaths();
- } else {
- supportMergePaths();
- }
-
-
- return path;
- }
-
- private void supportMergePaths() {
- for (int i = 0; i < pathContents.size(); i++) {
- path.addPath(pathContents.get(i).getPath());
- }
- }
-
- @TargetApi(Build.VERSION_CODES.KITKAT)
- private void mergePaths() {
-
switch (mergePaths.getMode()) {
case Merge:
- supportMergePaths();
+ addPaths();
break;
case Add:
opFirstPathWithRest(Path.Op.UNION);
@@ -70,6 +55,14 @@
opFirstPathWithRest(Path.Op.XOR);
break;
}
+
+ return path;
+ }
+
+ private void addPaths() {
+ for (int i = 0; i < pathContents.size(); i++) {
+ path.addPath(pathContents.get(i).getPath());
+ }
}
@TargetApi(Build.VERSION_CODES.KITKAT)
diff --git a/lottie/src/main/res/values/attrs.xml b/lottie/src/main/res/values/attrs.xml
index 8455945..5cf0434 100644
--- a/lottie/src/main/res/values/attrs.xml
+++ b/lottie/src/main/res/values/attrs.xml
@@ -6,6 +6,7 @@
<attr name="lottie_loop" format="boolean" />
<attr name="lottie_imageAssetsFolder" format="string" />
<attr name="lottie_progress" format="float" />
+ <attr name="lottie_enableMergePathsForKitKatAndAbove" format="boolean" />
<attr name="lottie_cacheStrategy" format="enum">
<enum name="none" value="0" />
<enum name="weak" value="1" />