From 6c218913aa78f8782791f6cc2a1653fcfc99417d Mon Sep 17 00:00:00 2001 From: Greg Giacovelli Date: Thu, 21 Oct 2021 17:30:51 -0700 Subject: [PATCH 1/5] Commit with local test passing --- .../java/com/airbnb/lottie/TextDelegate.java | 79 +- .../airbnb/lottie/model/layer/TextLayer.java | 2 +- .../airbnb/lottie/samples/HappoSnapshotter.kt | 1 + .../com/airbnb/lottie/samples/LottieTest.kt | 266 ++--- sample/src/main/assets/Tests/DynamicText.json | 952 +++++++++++++++++- 5 files changed, 1160 insertions(+), 140 deletions(-) diff --git a/lottie/src/main/java/com/airbnb/lottie/TextDelegate.java b/lottie/src/main/java/com/airbnb/lottie/TextDelegate.java index 1ae5a6ccef..4089be1df0 100644 --- a/lottie/src/main/java/com/airbnb/lottie/TextDelegate.java +++ b/lottie/src/main/java/com/airbnb/lottie/TextDelegate.java @@ -16,7 +16,42 @@ */ public class TextDelegate { - private final Map stringMap = new HashMap<>(); + private static class Key { + private final String layerName; + private final String input; + private Key(String layerName, String input) { + this.layerName = layerName; + this.input = input; + } + + private Key(String input) { + this(null, input); + } + + @Override public boolean equals(Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + + Key key = (Key) o; + + if (layerName != null ? !layerName.equals(key.layerName) : key.layerName != null) { + return false; + } + return input != null ? input.equals(key.input) : key.input == null; + } + + @Override public int hashCode() { + int result = layerName != null ? layerName.hashCode() : 0; + result = 31 * result + (input != null ? input.hashCode() : 0); + return result; + } + } + private final Map stringMap = new HashMap<>(); + @Nullable private final LottieAnimationView animationView; @Nullable private final LottieDrawable drawable; private boolean cacheText = true; @@ -41,6 +76,17 @@ public TextDelegate(@SuppressWarnings("NullableProblems") LottieDrawable drawabl animationView = null; } + /** + * Override this to replace the animation text with something dynamic. This + * can be used for translations or custom data + * @param layerName the name of the layer with text + * @param input the string at the layer with text + * @return a String to use for the specific data, by default this is the same as getText(input) + */ + public String getText(String layerName, String input) { + return getText(input); + } + /** * Override this to replace the animation text with something dynamic. This can be used for * translations or custom data. @@ -53,7 +99,12 @@ public String getText(String input) { * Update the text that will be rendered for the given input text. */ public void setText(String input, String output) { - stringMap.put(input, output); + stringMap.put(new Key(input), output); + invalidate(); + } + + public void setText(String layerName, String input, String output) { + stringMap.put(new Key(layerName, input), output); invalidate(); } @@ -65,11 +116,15 @@ public void setCacheText(boolean cacheText) { this.cacheText = cacheText; } + public void invalidateText(String layerName, String input) { + stringMap.remove(new Key(layerName, input)); + invalidate(); + } /** * Invalidates a cached string with the given input. */ public void invalidateText(String input) { - stringMap.remove(input); + stringMap.remove(new Key(input)); invalidate(); } @@ -82,13 +137,21 @@ public void invalidateAllText() { } @RestrictTo(RestrictTo.Scope.LIBRARY) - public final String getTextInternal(String input) { - if (cacheText && stringMap.containsKey(input)) { - return stringMap.get(input); + public final String getTextInternal(String layerName, String input) { + Key key = new Key(layerName, input); + if (cacheText) { + if (stringMap.containsKey(key)) { + return stringMap.get(key); + } + Key inputKey = new Key(input); + if (stringMap.containsKey(inputKey)) { + return stringMap.get(inputKey); + } } - String text = getText(input); + + String text = getText(layerName, input); if (cacheText) { - stringMap.put(input, text); + stringMap.put(key, text); } return text; } 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 b0f3b2d56d..e93e840c4a 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 @@ -245,7 +245,7 @@ private void drawTextWithFont( String text = documentData.text; TextDelegate textDelegate = lottieDrawable.getTextDelegate(); if (textDelegate != null) { - text = textDelegate.getTextInternal(text); + text = textDelegate.getTextInternal(getName(), text); } fillPaint.setTypeface(typeface); float textSize; diff --git a/sample/src/androidTest/java/com/airbnb/lottie/samples/HappoSnapshotter.kt b/sample/src/androidTest/java/com/airbnb/lottie/samples/HappoSnapshotter.kt index 59798100b5..a8caf15c79 100644 --- a/sample/src/androidTest/java/com/airbnb/lottie/samples/HappoSnapshotter.kt +++ b/sample/src/androidTest/java/com/airbnb/lottie/samples/HappoSnapshotter.kt @@ -106,6 +106,7 @@ class HappoSnapshotter( if (response.isSuccessful) { Log.d(TAG, "Uploaded $reportName to happo") } else { + println("$json") throw IllegalStateException("Failed to upload $reportName to Happo. Failed with code ${response.code}. " + response.body?.string()) } } diff --git a/sample/src/androidTest/java/com/airbnb/lottie/samples/LottieTest.kt b/sample/src/androidTest/java/com/airbnb/lottie/samples/LottieTest.kt index af2c9fc02c..967181825d 100644 --- a/sample/src/androidTest/java/com/airbnb/lottie/samples/LottieTest.kt +++ b/sample/src/androidTest/java/com/airbnb/lottie/samples/LottieTest.kt @@ -42,6 +42,7 @@ import java.io.FileInputStream import java.util.concurrent.Executors import java.util.concurrent.TimeUnit import java.util.zip.ZipInputStream +import kotlin.random.Random @ExperimentalCoroutinesApi @RunWith(AndroidJUnit4::class) @@ -101,20 +102,20 @@ class LottieTest { @Test fun testAll() = runBlocking { withTimeout(TimeUnit.MINUTES.toMillis(45)) { - testCustomBounds() - testColorStateListColorFilter() - testFailure() - snapshotFrameBoundaries() - snapshotScaleTypes() - testDynamicProperties() - testMarkers() - testAssets() +// testCustomBounds() +// testColorStateListColorFilter() +// testFailure() +// snapshotFrameBoundaries() +// snapshotScaleTypes() +// testDynamicProperties() +// testMarkers() +// testAssets() testText() - testPartialFrameProgress() - testProdAnimations() - testNightMode() - testApplyOpacityToLayer() - testOutlineMasksAndMattes() +// testPartialFrameProgress() +// testProdAnimations() +// testNightMode() +// testApplyOpacityToLayer() +// testOutlineMasksAndMattes() snapshotter.finalizeReportAndUpload() } } @@ -889,124 +890,131 @@ class LottieTest { } private suspend fun testText() { - withAnimationView("Tests/DynamicText.json", "Dynamic Text", "Hello World") { animationView -> +// withAnimationView("Tests/DynamicText.json", "Dynamic Text", "Hello World") { animationView -> +// val textDelegate = TextDelegate(animationView) +// animationView.setTextDelegate(textDelegate) +// textDelegate.setText("NAME", "Hello World") +// } +// +// withAnimationView("Tests/DynamicText.json", "Dynamic Text", "Hello World with getText") { animationView -> +// val textDelegate = object : TextDelegate(animationView) { +// override fun getText(input: String): String { +// return when (input) { +// "NAME" -> "Hello World" +// else -> input +// } +// } +// } +// animationView.setTextDelegate(textDelegate) +// } +// +// withAnimationView("Tests/DynamicText.json", "Dynamic Text", "Emoji") { animationView -> +// val textDelegate = TextDelegate(animationView) +// animationView.setTextDelegate(textDelegate) +// textDelegate.setText("NAME", "🔥💪💯") +// } +// +// withAnimationView("Tests/DynamicText.json", "Dynamic Text", "Taiwanese") { animationView -> +// val textDelegate = TextDelegate(animationView) +// animationView.setTextDelegate(textDelegate) +// textDelegate.setText("NAME", "我的密碼") +// } +// +// withAnimationView("Tests/DynamicText.json", "Dynamic Text", "Fire Taiwanese") { animationView -> +// val textDelegate = TextDelegate(animationView) +// animationView.setTextDelegate(textDelegate) +// textDelegate.setText("NAME", "🔥的A") +// } +// +// withAnimationView("Tests/DynamicText.json", "Dynamic Text", "Family man man girl boy") { animationView -> +// val textDelegate = TextDelegate(animationView) +// animationView.setTextDelegate(textDelegate) +// textDelegate.setText("NAME", "\uD83D\uDC68\u200D\uD83D\uDC68\u200D\uD83D\uDC67\u200D\uD83D\uDC66") +// } +// +// withAnimationView("Tests/DynamicText.json", "Dynamic Text", "Family woman woman girl girl") { animationView -> +// val textDelegate = TextDelegate(animationView) +// animationView.setTextDelegate(textDelegate) +// textDelegate.setText("NAME", "\uD83D\uDC69\u200D\uD83D\uDC69\u200D\uD83D\uDC67\u200D\uD83D\uDC67") +// } +// +// withAnimationView("Tests/DynamicText.json", "Dynamic Text", "Brown Police Man") { animationView -> +// val textDelegate = TextDelegate(animationView) +// animationView.setTextDelegate(textDelegate) +// textDelegate.setText("NAME", "\uD83D\uDC6E\uD83C\uDFFF\u200D♀️") +// } +// +// withAnimationView("Tests/DynamicText.json", "Dynamic Text", "Family and Brown Police Man") { animationView -> +// val textDelegate = TextDelegate(animationView) +// animationView.setTextDelegate(textDelegate) +// textDelegate.setText("NAME", "\uD83D\uDC68\u200D\uD83D\uDC68\u200D\uD83D\uDC67\u200D\uD83D\uDC67\uD83D\uDC6E\uD83C\uDFFF\u200D♀️") +// } +// +// withAnimationView("Tests/DynamicText.json", "Dynamic Text", "Family, Brown Police Man, emoji and chars") { animationView -> +// val textDelegate = TextDelegate(animationView) +// animationView.setTextDelegate(textDelegate) +// textDelegate.setText("NAME", "🔥\uD83D\uDC68\u200D\uD83D\uDC68\u200D\uD83D\uDC67\u200D\uD83D\uDC67\uD83D\uDC6E\uD83C\uDFFF\u200D♀的Aabc️") +// } +// +// withAnimationView("Tests/DynamicText.json", "Dynamic Text", "Fire English Fire Brown Police Man Fire") { animationView -> +// val textDelegate = TextDelegate(animationView) +// animationView.setTextDelegate(textDelegate) +// textDelegate.setText("NAME", "🔥c️🔥\uD83D\uDC6E\uD83C\uDFFF\u200D♀️\uD83D\uDD25") +// } +// +// withAnimationView("Tests/DynamicText.json", "Dynamic Text", "American Flag") { animationView -> +// val textDelegate = TextDelegate(animationView) +// animationView.setTextDelegate(textDelegate) +// textDelegate.setText("NAME", "\uD83C\uDDFA\uD83C\uDDF8") +// } +// +// withAnimationView("Tests/DynamicText.json", "Dynamic Text", "Checkered Flag") { animationView -> +// val textDelegate = TextDelegate(animationView) +// animationView.setTextDelegate(textDelegate) +// textDelegate.setText("NAME", "\uD83C\uDFC1") +// } +// +// withAnimationView("Tests/DynamicText.json", "Dynamic Text", "Pirate Flag") { animationView -> +// val textDelegate = TextDelegate(animationView) +// animationView.setTextDelegate(textDelegate) +// textDelegate.setText("NAME", "\uD83C\uDFF4\u200D☠️") +// } +// +// withAnimationView("Tests/DynamicText.json", "Dynamic Text", "3 Oclock") { animationView -> +// val textDelegate = TextDelegate(animationView) +// animationView.setTextDelegate(textDelegate) +// textDelegate.setText("NAME", "\uD83D\uDD52") +// } +// +// withAnimationView("Tests/DynamicText.json", "Dynamic Text", "Woman frowning") { animationView -> +// val textDelegate = TextDelegate(animationView) +// animationView.setTextDelegate(textDelegate) +// textDelegate.setText("NAME", "\uD83D\uDE4D\u200D♀️") +// } +// +// withAnimationView("Tests/DynamicText.json", "Dynamic Text", "Gay couple") { animationView -> +// val textDelegate = TextDelegate(animationView) +// animationView.setTextDelegate(textDelegate) +// textDelegate.setText("NAME", "\uD83D\uDC68\u200D❤️\u200D\uD83D\uDC68️") +// } +// +// withAnimationView("Tests/DynamicText.json", "Dynamic Text", "Lesbian couple") { animationView -> +// val textDelegate = TextDelegate(animationView) +// animationView.setTextDelegate(textDelegate) +// textDelegate.setText("NAME", "\uD83D\uDC69\u200D❤️\u200D\uD83D\uDC69️") +// } +// +// withAnimationView("Tests/DynamicText.json", "Dynamic Text", "Straight couple") { animationView -> +// val textDelegate = TextDelegate(animationView) +// animationView.setTextDelegate(textDelegate) +// textDelegate.setText("NAME", "\uD83D\uDC91") +// } + + withAnimationView("Tests/DynamicText.json", "Dynamic Text", "layer name different than text") { animationView -> val textDelegate = TextDelegate(animationView) animationView.setTextDelegate(textDelegate) - textDelegate.setText("NAME", "Hello World") - } - - withAnimationView("Tests/DynamicText.json", "Dynamic Text", "Hello World with getText") { animationView -> - val textDelegate = object : TextDelegate(animationView) { - override fun getText(input: String): String { - return when (input) { - "NAME" -> "Hello World" - else -> input - } - } - } - animationView.setTextDelegate(textDelegate) - } - - withAnimationView("Tests/DynamicText.json", "Dynamic Text", "Emoji") { animationView -> - val textDelegate = TextDelegate(animationView) - animationView.setTextDelegate(textDelegate) - textDelegate.setText("NAME", "🔥💪💯") - } - - withAnimationView("Tests/DynamicText.json", "Dynamic Text", "Taiwanese") { animationView -> - val textDelegate = TextDelegate(animationView) - animationView.setTextDelegate(textDelegate) - textDelegate.setText("NAME", "我的密碼") - } - - withAnimationView("Tests/DynamicText.json", "Dynamic Text", "Fire Taiwanese") { animationView -> - val textDelegate = TextDelegate(animationView) - animationView.setTextDelegate(textDelegate) - textDelegate.setText("NAME", "🔥的A") - } - - withAnimationView("Tests/DynamicText.json", "Dynamic Text", "Family man man girl boy") { animationView -> - val textDelegate = TextDelegate(animationView) - animationView.setTextDelegate(textDelegate) - textDelegate.setText("NAME", "\uD83D\uDC68\u200D\uD83D\uDC68\u200D\uD83D\uDC67\u200D\uD83D\uDC66") - } - - withAnimationView("Tests/DynamicText.json", "Dynamic Text", "Family woman woman girl girl") { animationView -> - val textDelegate = TextDelegate(animationView) - animationView.setTextDelegate(textDelegate) - textDelegate.setText("NAME", "\uD83D\uDC69\u200D\uD83D\uDC69\u200D\uD83D\uDC67\u200D\uD83D\uDC67") - } - - withAnimationView("Tests/DynamicText.json", "Dynamic Text", "Brown Police Man") { animationView -> - val textDelegate = TextDelegate(animationView) - animationView.setTextDelegate(textDelegate) - textDelegate.setText("NAME", "\uD83D\uDC6E\uD83C\uDFFF\u200D♀️") - } - - withAnimationView("Tests/DynamicText.json", "Dynamic Text", "Family and Brown Police Man") { animationView -> - val textDelegate = TextDelegate(animationView) - animationView.setTextDelegate(textDelegate) - textDelegate.setText("NAME", "\uD83D\uDC68\u200D\uD83D\uDC68\u200D\uD83D\uDC67\u200D\uD83D\uDC67\uD83D\uDC6E\uD83C\uDFFF\u200D♀️") - } - - withAnimationView("Tests/DynamicText.json", "Dynamic Text", "Family, Brown Police Man, emoji and chars") { animationView -> - val textDelegate = TextDelegate(animationView) - animationView.setTextDelegate(textDelegate) - textDelegate.setText("NAME", "🔥\uD83D\uDC68\u200D\uD83D\uDC68\u200D\uD83D\uDC67\u200D\uD83D\uDC67\uD83D\uDC6E\uD83C\uDFFF\u200D♀的Aabc️") - } - - withAnimationView("Tests/DynamicText.json", "Dynamic Text", "Fire English Fire Brown Police Man Fire") { animationView -> - val textDelegate = TextDelegate(animationView) - animationView.setTextDelegate(textDelegate) - textDelegate.setText("NAME", "🔥c️🔥\uD83D\uDC6E\uD83C\uDFFF\u200D♀️\uD83D\uDD25") - } - - withAnimationView("Tests/DynamicText.json", "Dynamic Text", "American Flag") { animationView -> - val textDelegate = TextDelegate(animationView) - animationView.setTextDelegate(textDelegate) - textDelegate.setText("NAME", "\uD83C\uDDFA\uD83C\uDDF8") - } - - withAnimationView("Tests/DynamicText.json", "Dynamic Text", "Checkered Flag") { animationView -> - val textDelegate = TextDelegate(animationView) - animationView.setTextDelegate(textDelegate) - textDelegate.setText("NAME", "\uD83C\uDFC1") - } - - withAnimationView("Tests/DynamicText.json", "Dynamic Text", "Pirate Flag") { animationView -> - val textDelegate = TextDelegate(animationView) - animationView.setTextDelegate(textDelegate) - textDelegate.setText("NAME", "\uD83C\uDFF4\u200D☠️") - } - - withAnimationView("Tests/DynamicText.json", "Dynamic Text", "3 Oclock") { animationView -> - val textDelegate = TextDelegate(animationView) - animationView.setTextDelegate(textDelegate) - textDelegate.setText("NAME", "\uD83D\uDD52") - } - - withAnimationView("Tests/DynamicText.json", "Dynamic Text", "Woman frowning") { animationView -> - val textDelegate = TextDelegate(animationView) - animationView.setTextDelegate(textDelegate) - textDelegate.setText("NAME", "\uD83D\uDE4D\u200D♀️") - } - - withAnimationView("Tests/DynamicText.json", "Dynamic Text", "Gay couple") { animationView -> - val textDelegate = TextDelegate(animationView) - animationView.setTextDelegate(textDelegate) - textDelegate.setText("NAME", "\uD83D\uDC68\u200D❤️\u200D\uD83D\uDC68️") - } - - withAnimationView("Tests/DynamicText.json", "Dynamic Text", "Lesbian couple") { animationView -> - val textDelegate = TextDelegate(animationView) - animationView.setTextDelegate(textDelegate) - textDelegate.setText("NAME", "\uD83D\uDC69\u200D❤️\u200D\uD83D\uDC69️") - } - - withAnimationView("Tests/DynamicText.json", "Dynamic Text", "Straight couple") { animationView -> - val textDelegate = TextDelegate(animationView) - animationView.setTextDelegate(textDelegate) - textDelegate.setText("NAME", "\uD83D\uDC91") + textDelegate.setText("NAME", "Layer named Name") + textDelegate.setText("Name Not matching Text", "NAME", "Some Other Name " + Random.nextDouble()) } } diff --git a/sample/src/main/assets/Tests/DynamicText.json b/sample/src/main/assets/Tests/DynamicText.json index fad053c83f..e97e284d1c 100644 --- a/sample/src/main/assets/Tests/DynamicText.json +++ b/sample/src/main/assets/Tests/DynamicText.json @@ -1,2 +1,950 @@ -{"v":"4.8.0","fr":29.9700012207031,"ip":0,"op":61.0000024845809,"w":150,"h":150,"nm":"Name", - "ddd":0,"assets":[],"fonts":{"list":[{"origin":0,"fPath":"","fClass":"","fFamily":"Comic Neue","fWeight":"","fStyle":"Regular","fName":"ComicNeue","ascent":69.6990966796875}]},"layers":[{"ddd":0,"ind":1,"ty":5,"nm":"NAME","ks":{"o":{"a":0,"k":100},"r":{"a":0,"k":0},"p":{"a":1,"k":[{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":0,"s":[10.5,15,0],"e":[10.5,147,0],"to":[0,22,0],"ti":[0,0,0]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":15,"s":[10.5,147,0],"e":[10.5,15,0],"to":[0,0,0],"ti":[0,22,0]},{"t":30.0000012219251}]},"a":{"a":0,"k":[0,0,0]},"s":{"a":1,"k":[{"i":{"x":[0.833,0.833,0.833],"y":[0.833,0.833,0.833]},"o":{"x":[0.167,0.167,0.167],"y":[0.167,0.167,0.167]},"n":["0p833_0p833_0p167_0p167","0p833_0p833_0p167_0p167","0p833_0p833_0p167_0p167"],"t":0,"s":[100,100,100],"e":[196,196,100]},{"i":{"x":[0.833,0.833,0.833],"y":[0.833,0.833,0.833]},"o":{"x":[0.167,0.167,0.167],"y":[0.167,0.167,0.167]},"n":["0p833_0p833_0p167_0p167","0p833_0p833_0p167_0p167","0p833_0p833_0p167_0p167"],"t":15,"s":[196,196,100],"e":[100,100,100]},{"t":30.0000012219251}]}},"ao":0,"t":{"d":{"k":[{"s":{"s":14,"f":"ComicNeue","t":"NAME","j":0,"tr":0,"lh":16.8,"ls":0,"fc":[0.92,0,0]},"t":0}]},"p":{},"m":{"g":1,"a":{"a":0,"k":[0,0]}},"a":[{"s":{"t":0,"xe":{"a":0,"k":0},"ne":{"a":0,"k":0},"a":{"a":0,"k":100},"b":1,"rn":0,"sh":1,"r":1},"a":{"fc":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":0,"s":[1,0,0,1],"e":[0,1,0,1]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":15,"s":[0,1,0,1],"e":[0,0,1,1]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":30,"s":[0,0,1,1],"e":[0,1,0,1]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":45,"s":[0,1,0,1],"e":[1,0,0,1]},{"t":60.0000024438501}]},"t":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":30,"s":[0],"e":[20]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":45,"s":[20],"e":[0]},{"t":60.0000024438501}]}}}]},"ip":0,"op":61.0000024845809,"st":0,"bm":0,"sr":1}]} \ No newline at end of file +{ + "v": "4.8.0", + "fr": 29.9700012207031, + "ip": 0, + "op": 61.0000024845809, + "w": 150, + "h": 150, + "nm": "Name", + "ddd": 0, + "assets": [], + "fonts": { + "list": [ + { + "origin": 0, + "fPath": "", + "fClass": "", + "fFamily": "Comic Neue", + "fWeight": "", + "fStyle": "Regular", + "fName": "ComicNeue", + "ascent": 69.6990966796875 + } + ] + }, + "layers": [ + { + "ddd": 0, + "ind": 1, + "ty": 5, + "nm": "NAME", + "ks": { + "o": { + "a": 0, + "k": 100 + }, + "r": { + "a": 0, + "k": 0 + }, + "p": { + "a": 1, + "k": [ + { + "i": { + "x": 0.833, + "y": 0.833 + }, + "o": { + "x": 0.167, + "y": 0.167 + }, + "n": "0p833_0p833_0p167_0p167", + "t": 0, + "s": [ + 10.5, + 15, + 0 + ], + "e": [ + 10.5, + 147, + 0 + ], + "to": [ + 0, + 22, + 0 + ], + "ti": [ + 0, + 0, + 0 + ] + }, + { + "i": { + "x": 0.833, + "y": 0.833 + }, + "o": { + "x": 0.167, + "y": 0.167 + }, + "n": "0p833_0p833_0p167_0p167", + "t": 15, + "s": [ + 10.5, + 147, + 0 + ], + "e": [ + 10.5, + 15, + 0 + ], + "to": [ + 0, + 0, + 0 + ], + "ti": [ + 0, + 22, + 0 + ] + }, + { + "t": 30.0000012219251 + } + ] + }, + "a": { + "a": 0, + "k": [ + 0, + 0, + 0 + ] + }, + "s": { + "a": 1, + "k": [ + { + "i": { + "x": [ + 0.833, + 0.833, + 0.833 + ], + "y": [ + 0.833, + 0.833, + 0.833 + ] + }, + "o": { + "x": [ + 0.167, + 0.167, + 0.167 + ], + "y": [ + 0.167, + 0.167, + 0.167 + ] + }, + "n": [ + "0p833_0p833_0p167_0p167", + "0p833_0p833_0p167_0p167", + "0p833_0p833_0p167_0p167" + ], + "t": 0, + "s": [ + 100, + 100, + 100 + ], + "e": [ + 196, + 196, + 100 + ] + }, + { + "i": { + "x": [ + 0.833, + 0.833, + 0.833 + ], + "y": [ + 0.833, + 0.833, + 0.833 + ] + }, + "o": { + "x": [ + 0.167, + 0.167, + 0.167 + ], + "y": [ + 0.167, + 0.167, + 0.167 + ] + }, + "n": [ + "0p833_0p833_0p167_0p167", + "0p833_0p833_0p167_0p167", + "0p833_0p833_0p167_0p167" + ], + "t": 15, + "s": [ + 196, + 196, + 100 + ], + "e": [ + 100, + 100, + 100 + ] + }, + { + "t": 30.0000012219251 + } + ] + } + }, + "ao": 0, + "t": { + "d": { + "k": [ + { + "s": { + "s": 14, + "f": "ComicNeue", + "t": "NAME", + "j": 0, + "tr": 0, + "lh": 16.8, + "ls": 0, + "fc": [ + 0.92, + 0, + 0 + ] + }, + "t": 0 + } + ] + }, + "p": {}, + "m": { + "g": 1, + "a": { + "a": 0, + "k": [ + 0, + 0 + ] + } + }, + "a": [ + { + "s": { + "t": 0, + "xe": { + "a": 0, + "k": 0 + }, + "ne": { + "a": 0, + "k": 0 + }, + "a": { + "a": 0, + "k": 100 + }, + "b": 1, + "rn": 0, + "sh": 1, + "r": 1 + }, + "a": { + "fc": { + "a": 1, + "k": [ + { + "i": { + "x": [ + 0.833 + ], + "y": [ + 0.833 + ] + }, + "o": { + "x": [ + 0.167 + ], + "y": [ + 0.167 + ] + }, + "n": [ + "0p833_0p833_0p167_0p167" + ], + "t": 0, + "s": [ + 1, + 0, + 0, + 1 + ], + "e": [ + 0, + 1, + 0, + 1 + ] + }, + { + "i": { + "x": [ + 0.833 + ], + "y": [ + 0.833 + ] + }, + "o": { + "x": [ + 0.167 + ], + "y": [ + 0.167 + ] + }, + "n": [ + "0p833_0p833_0p167_0p167" + ], + "t": 15, + "s": [ + 0, + 1, + 0, + 1 + ], + "e": [ + 0, + 0, + 1, + 1 + ] + }, + { + "i": { + "x": [ + 0.833 + ], + "y": [ + 0.833 + ] + }, + "o": { + "x": [ + 0.167 + ], + "y": [ + 0.167 + ] + }, + "n": [ + "0p833_0p833_0p167_0p167" + ], + "t": 30, + "s": [ + 0, + 0, + 1, + 1 + ], + "e": [ + 0, + 1, + 0, + 1 + ] + }, + { + "i": { + "x": [ + 0.833 + ], + "y": [ + 0.833 + ] + }, + "o": { + "x": [ + 0.167 + ], + "y": [ + 0.167 + ] + }, + "n": [ + "0p833_0p833_0p167_0p167" + ], + "t": 45, + "s": [ + 0, + 1, + 0, + 1 + ], + "e": [ + 1, + 0, + 0, + 1 + ] + }, + { + "t": 60.0000024438501 + } + ] + }, + "t": { + "a": 1, + "k": [ + { + "i": { + "x": [ + 0.833 + ], + "y": [ + 0.833 + ] + }, + "o": { + "x": [ + 0.167 + ], + "y": [ + 0.167 + ] + }, + "n": [ + "0p833_0p833_0p167_0p167" + ], + "t": 30, + "s": [ + 0 + ], + "e": [ + 20 + ] + }, + { + "i": { + "x": [ + 0.833 + ], + "y": [ + 0.833 + ] + }, + "o": { + "x": [ + 0.167 + ], + "y": [ + 0.167 + ] + }, + "n": [ + "0p833_0p833_0p167_0p167" + ], + "t": 45, + "s": [ + 20 + ], + "e": [ + 0 + ] + }, + { + "t": 60.0000024438501 + } + ] + } + } + } + ] + }, + "ip": 0, + "op": 61.0000024845809, + "st": 0, + "bm": 0, + "sr": 1 + }, + { + "ddd": 0, + "ind": 1, + "ty": 5, + "nm": "Name Not matching Text", + "ks": { + "o": { + "a": 0, + "k": 100 + }, + "r": { + "a": 0, + "k": 0 + }, + "p": { + "a": 1, + "k": [ + { + "i": { + "x": 0.833, + "y": 0.833 + }, + "o": { + "x": 0.167, + "y": 0.167 + }, + "n": "0p833_0p833_0p167_0p167", + "t": 0, + "s": [ + 10.5, + 15, + 0 + ], + "e": [ + 10.5, + 147, + 0 + ], + "to": [ + 0, + 22, + 0 + ], + "ti": [ + 0, + 0, + 0 + ] + }, + { + "i": { + "x": 0.833, + "y": 0.833 + }, + "o": { + "x": 0.167, + "y": 0.167 + }, + "n": "0p833_0p833_0p167_0p167", + "t": 15, + "s": [ + 10.5, + 147, + 0 + ], + "e": [ + 10.5, + 15, + 0 + ], + "to": [ + 0, + 0, + 0 + ], + "ti": [ + 0, + 22, + 0 + ] + }, + { + "t": 30.0000012219251 + } + ] + }, + "a": { + "a": 0, + "k": [ + 0, + 0, + 0 + ] + }, + "s": { + "a": 1, + "k": [ + { + "i": { + "x": [ + 0.833, + 0.833, + 0.833 + ], + "y": [ + 0.833, + 0.833, + 0.833 + ] + }, + "o": { + "x": [ + 0.167, + 0.167, + 0.167 + ], + "y": [ + 0.167, + 0.167, + 0.167 + ] + }, + "n": [ + "0p833_0p833_0p167_0p167", + "0p833_0p833_0p167_0p167", + "0p833_0p833_0p167_0p167" + ], + "t": 0, + "s": [ + 100, + 100, + 100 + ], + "e": [ + 196, + 196, + 100 + ] + }, + { + "i": { + "x": [ + 0.833, + 0.833, + 0.833 + ], + "y": [ + 0.833, + 0.833, + 0.833 + ] + }, + "o": { + "x": [ + 0.167, + 0.167, + 0.167 + ], + "y": [ + 0.167, + 0.167, + 0.167 + ] + }, + "n": [ + "0p833_0p833_0p167_0p167", + "0p833_0p833_0p167_0p167", + "0p833_0p833_0p167_0p167" + ], + "t": 15, + "s": [ + 196, + 196, + 100 + ], + "e": [ + 100, + 100, + 100 + ] + }, + { + "t": 30.0000012219251 + } + ] + } + }, + "ao": 0, + "t": { + "d": { + "k": [ + { + "s": { + "s": 14, + "f": "ComicNeue", + "t": "NAME", + "j": 0, + "tr": 0, + "lh": 16.8, + "ls": 0, + "fc": [ + 0.92, + 0, + 0 + ] + }, + "t": 0 + } + ] + }, + "p": {}, + "m": { + "g": 1, + "a": { + "a": 0, + "k": [ + 0, + 0 + ] + } + }, + "a": [ + { + "s": { + "t": 0, + "xe": { + "a": 0, + "k": 0 + }, + "ne": { + "a": 0, + "k": 0 + }, + "a": { + "a": 0, + "k": 100 + }, + "b": 1, + "rn": 0, + "sh": 1, + "r": 1 + }, + "a": { + "fc": { + "a": 1, + "k": [ + { + "i": { + "x": [ + 0.833 + ], + "y": [ + 0.833 + ] + }, + "o": { + "x": [ + 0.167 + ], + "y": [ + 0.167 + ] + }, + "n": [ + "0p833_0p833_0p167_0p167" + ], + "t": 0, + "s": [ + 1, + 0, + 0, + 1 + ], + "e": [ + 0, + 1, + 0, + 1 + ] + }, + { + "i": { + "x": [ + 0.833 + ], + "y": [ + 0.833 + ] + }, + "o": { + "x": [ + 0.167 + ], + "y": [ + 0.167 + ] + }, + "n": [ + "0p833_0p833_0p167_0p167" + ], + "t": 15, + "s": [ + 0, + 1, + 0, + 1 + ], + "e": [ + 0, + 0, + 1, + 1 + ] + }, + { + "i": { + "x": [ + 0.833 + ], + "y": [ + 0.833 + ] + }, + "o": { + "x": [ + 0.167 + ], + "y": [ + 0.167 + ] + }, + "n": [ + "0p833_0p833_0p167_0p167" + ], + "t": 30, + "s": [ + 0, + 0, + 1, + 1 + ], + "e": [ + 0, + 1, + 0, + 1 + ] + }, + { + "i": { + "x": [ + 0.833 + ], + "y": [ + 0.833 + ] + }, + "o": { + "x": [ + 0.167 + ], + "y": [ + 0.167 + ] + }, + "n": [ + "0p833_0p833_0p167_0p167" + ], + "t": 45, + "s": [ + 0, + 1, + 0, + 1 + ], + "e": [ + 1, + 0, + 0, + 1 + ] + }, + { + "t": 60.0000024438501 + } + ] + }, + "t": { + "a": 1, + "k": [ + { + "i": { + "x": [ + 0.833 + ], + "y": [ + 0.833 + ] + }, + "o": { + "x": [ + 0.167 + ], + "y": [ + 0.167 + ] + }, + "n": [ + "0p833_0p833_0p167_0p167" + ], + "t": 30, + "s": [ + 0 + ], + "e": [ + 20 + ] + }, + { + "i": { + "x": [ + 0.833 + ], + "y": [ + 0.833 + ] + }, + "o": { + "x": [ + 0.167 + ], + "y": [ + 0.167 + ] + }, + "n": [ + "0p833_0p833_0p167_0p167" + ], + "t": 45, + "s": [ + 20 + ], + "e": [ + 0 + ] + }, + { + "t": 60.0000024438501 + } + ] + } + } + } + ] + }, + "ip": 0, + "op": 61.0000024845809, + "st": 0, + "bm": 0, + "sr": 1 + } + + ] +} \ No newline at end of file From a9bcd9b003fca22af50d3c796a47e9c00abf1982 Mon Sep 17 00:00:00 2001 From: Greg Giacovelli Date: Thu, 21 Oct 2021 17:43:46 -0700 Subject: [PATCH 2/5] Expanding TextDelegate to provide similar functionality as iOS TextProvider --- .../java/com/airbnb/lottie/TextDelegate.java | 77 +- .../airbnb/lottie/model/layer/TextLayer.java | 3 +- .../airbnb/lottie/samples/HappoSnapshotter.kt | 1 - .../com/airbnb/lottie/samples/LottieTest.kt | 266 +++-- sample/src/main/assets/Tests/DynamicText.json | 952 +----------------- 5 files changed, 147 insertions(+), 1152 deletions(-) diff --git a/lottie/src/main/java/com/airbnb/lottie/TextDelegate.java b/lottie/src/main/java/com/airbnb/lottie/TextDelegate.java index 4089be1df0..31d80c08d6 100644 --- a/lottie/src/main/java/com/airbnb/lottie/TextDelegate.java +++ b/lottie/src/main/java/com/airbnb/lottie/TextDelegate.java @@ -4,6 +4,8 @@ import androidx.annotation.RestrictTo; import androidx.annotation.VisibleForTesting; +import com.airbnb.lottie.model.KeyPath; + import java.util.HashMap; import java.util.Map; @@ -16,41 +18,7 @@ */ public class TextDelegate { - private static class Key { - private final String layerName; - private final String input; - private Key(String layerName, String input) { - this.layerName = layerName; - this.input = input; - } - - private Key(String input) { - this(null, input); - } - - @Override public boolean equals(Object o) { - if (this == o) { - return true; - } - if (o == null || getClass() != o.getClass()) { - return false; - } - - Key key = (Key) o; - - if (layerName != null ? !layerName.equals(key.layerName) : key.layerName != null) { - return false; - } - return input != null ? input.equals(key.input) : key.input == null; - } - - @Override public int hashCode() { - int result = layerName != null ? layerName.hashCode() : 0; - result = 31 * result + (input != null ? input.hashCode() : 0); - return result; - } - } - private final Map stringMap = new HashMap<>(); + private final Map stringMap = new HashMap<>(); @Nullable private final LottieAnimationView animationView; @Nullable private final LottieDrawable drawable; @@ -77,13 +45,13 @@ public TextDelegate(@SuppressWarnings("NullableProblems") LottieDrawable drawabl } /** - * Override this to replace the animation text with something dynamic. This - * can be used for translations or custom data - * @param layerName the name of the layer with text + * Override this to replace the animation text with something dynamic. This can be used for + * translations or custom data. + * @param path the name of the layer with text * @param input the string at the layer with text * @return a String to use for the specific data, by default this is the same as getText(input) */ - public String getText(String layerName, String input) { + public String getText(KeyPath path, String input) { return getText(input); } @@ -99,12 +67,7 @@ public String getText(String input) { * Update the text that will be rendered for the given input text. */ public void setText(String input, String output) { - stringMap.put(new Key(input), output); - invalidate(); - } - - public void setText(String layerName, String input, String output) { - stringMap.put(new Key(layerName, input), output); + stringMap.put(input, output); invalidate(); } @@ -116,15 +79,11 @@ public void setCacheText(boolean cacheText) { this.cacheText = cacheText; } - public void invalidateText(String layerName, String input) { - stringMap.remove(new Key(layerName, input)); - invalidate(); - } /** * Invalidates a cached string with the given input. */ public void invalidateText(String input) { - stringMap.remove(new Key(input)); + stringMap.remove(input); invalidate(); } @@ -137,21 +96,13 @@ public void invalidateAllText() { } @RestrictTo(RestrictTo.Scope.LIBRARY) - public final String getTextInternal(String layerName, String input) { - Key key = new Key(layerName, input); - if (cacheText) { - if (stringMap.containsKey(key)) { - return stringMap.get(key); - } - Key inputKey = new Key(input); - if (stringMap.containsKey(inputKey)) { - return stringMap.get(inputKey); - } + public final String getTextInternal(KeyPath path, String input) { + if (cacheText && stringMap.containsKey(input)) { + return stringMap.get(input); } - - String text = getText(layerName, input); + String text = getText(path, input); if (cacheText) { - stringMap.put(key, text); + stringMap.put(input, text); } return text; } 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 e93e840c4a..5b959ecad2 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 @@ -23,6 +23,7 @@ import com.airbnb.lottie.model.DocumentData.Justification; import com.airbnb.lottie.model.Font; import com.airbnb.lottie.model.FontCharacter; +import com.airbnb.lottie.model.KeyPath; import com.airbnb.lottie.model.animatable.AnimatableTextProperties; import com.airbnb.lottie.model.content.ShapeGroup; import com.airbnb.lottie.utils.Utils; @@ -245,7 +246,7 @@ private void drawTextWithFont( String text = documentData.text; TextDelegate textDelegate = lottieDrawable.getTextDelegate(); if (textDelegate != null) { - text = textDelegate.getTextInternal(getName(), text); + text = textDelegate.getTextInternal(new KeyPath(getName()), text); } fillPaint.setTypeface(typeface); float textSize; diff --git a/sample/src/androidTest/java/com/airbnb/lottie/samples/HappoSnapshotter.kt b/sample/src/androidTest/java/com/airbnb/lottie/samples/HappoSnapshotter.kt index a8caf15c79..59798100b5 100644 --- a/sample/src/androidTest/java/com/airbnb/lottie/samples/HappoSnapshotter.kt +++ b/sample/src/androidTest/java/com/airbnb/lottie/samples/HappoSnapshotter.kt @@ -106,7 +106,6 @@ class HappoSnapshotter( if (response.isSuccessful) { Log.d(TAG, "Uploaded $reportName to happo") } else { - println("$json") throw IllegalStateException("Failed to upload $reportName to Happo. Failed with code ${response.code}. " + response.body?.string()) } } diff --git a/sample/src/androidTest/java/com/airbnb/lottie/samples/LottieTest.kt b/sample/src/androidTest/java/com/airbnb/lottie/samples/LottieTest.kt index 967181825d..af2c9fc02c 100644 --- a/sample/src/androidTest/java/com/airbnb/lottie/samples/LottieTest.kt +++ b/sample/src/androidTest/java/com/airbnb/lottie/samples/LottieTest.kt @@ -42,7 +42,6 @@ import java.io.FileInputStream import java.util.concurrent.Executors import java.util.concurrent.TimeUnit import java.util.zip.ZipInputStream -import kotlin.random.Random @ExperimentalCoroutinesApi @RunWith(AndroidJUnit4::class) @@ -102,20 +101,20 @@ class LottieTest { @Test fun testAll() = runBlocking { withTimeout(TimeUnit.MINUTES.toMillis(45)) { -// testCustomBounds() -// testColorStateListColorFilter() -// testFailure() -// snapshotFrameBoundaries() -// snapshotScaleTypes() -// testDynamicProperties() -// testMarkers() -// testAssets() + testCustomBounds() + testColorStateListColorFilter() + testFailure() + snapshotFrameBoundaries() + snapshotScaleTypes() + testDynamicProperties() + testMarkers() + testAssets() testText() -// testPartialFrameProgress() -// testProdAnimations() -// testNightMode() -// testApplyOpacityToLayer() -// testOutlineMasksAndMattes() + testPartialFrameProgress() + testProdAnimations() + testNightMode() + testApplyOpacityToLayer() + testOutlineMasksAndMattes() snapshotter.finalizeReportAndUpload() } } @@ -890,131 +889,124 @@ class LottieTest { } private suspend fun testText() { -// withAnimationView("Tests/DynamicText.json", "Dynamic Text", "Hello World") { animationView -> -// val textDelegate = TextDelegate(animationView) -// animationView.setTextDelegate(textDelegate) -// textDelegate.setText("NAME", "Hello World") -// } -// -// withAnimationView("Tests/DynamicText.json", "Dynamic Text", "Hello World with getText") { animationView -> -// val textDelegate = object : TextDelegate(animationView) { -// override fun getText(input: String): String { -// return when (input) { -// "NAME" -> "Hello World" -// else -> input -// } -// } -// } -// animationView.setTextDelegate(textDelegate) -// } -// -// withAnimationView("Tests/DynamicText.json", "Dynamic Text", "Emoji") { animationView -> -// val textDelegate = TextDelegate(animationView) -// animationView.setTextDelegate(textDelegate) -// textDelegate.setText("NAME", "🔥💪💯") -// } -// -// withAnimationView("Tests/DynamicText.json", "Dynamic Text", "Taiwanese") { animationView -> -// val textDelegate = TextDelegate(animationView) -// animationView.setTextDelegate(textDelegate) -// textDelegate.setText("NAME", "我的密碼") -// } -// -// withAnimationView("Tests/DynamicText.json", "Dynamic Text", "Fire Taiwanese") { animationView -> -// val textDelegate = TextDelegate(animationView) -// animationView.setTextDelegate(textDelegate) -// textDelegate.setText("NAME", "🔥的A") -// } -// -// withAnimationView("Tests/DynamicText.json", "Dynamic Text", "Family man man girl boy") { animationView -> -// val textDelegate = TextDelegate(animationView) -// animationView.setTextDelegate(textDelegate) -// textDelegate.setText("NAME", "\uD83D\uDC68\u200D\uD83D\uDC68\u200D\uD83D\uDC67\u200D\uD83D\uDC66") -// } -// -// withAnimationView("Tests/DynamicText.json", "Dynamic Text", "Family woman woman girl girl") { animationView -> -// val textDelegate = TextDelegate(animationView) -// animationView.setTextDelegate(textDelegate) -// textDelegate.setText("NAME", "\uD83D\uDC69\u200D\uD83D\uDC69\u200D\uD83D\uDC67\u200D\uD83D\uDC67") -// } -// -// withAnimationView("Tests/DynamicText.json", "Dynamic Text", "Brown Police Man") { animationView -> -// val textDelegate = TextDelegate(animationView) -// animationView.setTextDelegate(textDelegate) -// textDelegate.setText("NAME", "\uD83D\uDC6E\uD83C\uDFFF\u200D♀️") -// } -// -// withAnimationView("Tests/DynamicText.json", "Dynamic Text", "Family and Brown Police Man") { animationView -> -// val textDelegate = TextDelegate(animationView) -// animationView.setTextDelegate(textDelegate) -// textDelegate.setText("NAME", "\uD83D\uDC68\u200D\uD83D\uDC68\u200D\uD83D\uDC67\u200D\uD83D\uDC67\uD83D\uDC6E\uD83C\uDFFF\u200D♀️") -// } -// -// withAnimationView("Tests/DynamicText.json", "Dynamic Text", "Family, Brown Police Man, emoji and chars") { animationView -> -// val textDelegate = TextDelegate(animationView) -// animationView.setTextDelegate(textDelegate) -// textDelegate.setText("NAME", "🔥\uD83D\uDC68\u200D\uD83D\uDC68\u200D\uD83D\uDC67\u200D\uD83D\uDC67\uD83D\uDC6E\uD83C\uDFFF\u200D♀的Aabc️") -// } -// -// withAnimationView("Tests/DynamicText.json", "Dynamic Text", "Fire English Fire Brown Police Man Fire") { animationView -> -// val textDelegate = TextDelegate(animationView) -// animationView.setTextDelegate(textDelegate) -// textDelegate.setText("NAME", "🔥c️🔥\uD83D\uDC6E\uD83C\uDFFF\u200D♀️\uD83D\uDD25") -// } -// -// withAnimationView("Tests/DynamicText.json", "Dynamic Text", "American Flag") { animationView -> -// val textDelegate = TextDelegate(animationView) -// animationView.setTextDelegate(textDelegate) -// textDelegate.setText("NAME", "\uD83C\uDDFA\uD83C\uDDF8") -// } -// -// withAnimationView("Tests/DynamicText.json", "Dynamic Text", "Checkered Flag") { animationView -> -// val textDelegate = TextDelegate(animationView) -// animationView.setTextDelegate(textDelegate) -// textDelegate.setText("NAME", "\uD83C\uDFC1") -// } -// -// withAnimationView("Tests/DynamicText.json", "Dynamic Text", "Pirate Flag") { animationView -> -// val textDelegate = TextDelegate(animationView) -// animationView.setTextDelegate(textDelegate) -// textDelegate.setText("NAME", "\uD83C\uDFF4\u200D☠️") -// } -// -// withAnimationView("Tests/DynamicText.json", "Dynamic Text", "3 Oclock") { animationView -> -// val textDelegate = TextDelegate(animationView) -// animationView.setTextDelegate(textDelegate) -// textDelegate.setText("NAME", "\uD83D\uDD52") -// } -// -// withAnimationView("Tests/DynamicText.json", "Dynamic Text", "Woman frowning") { animationView -> -// val textDelegate = TextDelegate(animationView) -// animationView.setTextDelegate(textDelegate) -// textDelegate.setText("NAME", "\uD83D\uDE4D\u200D♀️") -// } -// -// withAnimationView("Tests/DynamicText.json", "Dynamic Text", "Gay couple") { animationView -> -// val textDelegate = TextDelegate(animationView) -// animationView.setTextDelegate(textDelegate) -// textDelegate.setText("NAME", "\uD83D\uDC68\u200D❤️\u200D\uD83D\uDC68️") -// } -// -// withAnimationView("Tests/DynamicText.json", "Dynamic Text", "Lesbian couple") { animationView -> -// val textDelegate = TextDelegate(animationView) -// animationView.setTextDelegate(textDelegate) -// textDelegate.setText("NAME", "\uD83D\uDC69\u200D❤️\u200D\uD83D\uDC69️") -// } -// -// withAnimationView("Tests/DynamicText.json", "Dynamic Text", "Straight couple") { animationView -> -// val textDelegate = TextDelegate(animationView) -// animationView.setTextDelegate(textDelegate) -// textDelegate.setText("NAME", "\uD83D\uDC91") -// } - - withAnimationView("Tests/DynamicText.json", "Dynamic Text", "layer name different than text") { animationView -> + withAnimationView("Tests/DynamicText.json", "Dynamic Text", "Hello World") { animationView -> val textDelegate = TextDelegate(animationView) animationView.setTextDelegate(textDelegate) - textDelegate.setText("NAME", "Layer named Name") - textDelegate.setText("Name Not matching Text", "NAME", "Some Other Name " + Random.nextDouble()) + textDelegate.setText("NAME", "Hello World") + } + + withAnimationView("Tests/DynamicText.json", "Dynamic Text", "Hello World with getText") { animationView -> + val textDelegate = object : TextDelegate(animationView) { + override fun getText(input: String): String { + return when (input) { + "NAME" -> "Hello World" + else -> input + } + } + } + animationView.setTextDelegate(textDelegate) + } + + withAnimationView("Tests/DynamicText.json", "Dynamic Text", "Emoji") { animationView -> + val textDelegate = TextDelegate(animationView) + animationView.setTextDelegate(textDelegate) + textDelegate.setText("NAME", "🔥💪💯") + } + + withAnimationView("Tests/DynamicText.json", "Dynamic Text", "Taiwanese") { animationView -> + val textDelegate = TextDelegate(animationView) + animationView.setTextDelegate(textDelegate) + textDelegate.setText("NAME", "我的密碼") + } + + withAnimationView("Tests/DynamicText.json", "Dynamic Text", "Fire Taiwanese") { animationView -> + val textDelegate = TextDelegate(animationView) + animationView.setTextDelegate(textDelegate) + textDelegate.setText("NAME", "🔥的A") + } + + withAnimationView("Tests/DynamicText.json", "Dynamic Text", "Family man man girl boy") { animationView -> + val textDelegate = TextDelegate(animationView) + animationView.setTextDelegate(textDelegate) + textDelegate.setText("NAME", "\uD83D\uDC68\u200D\uD83D\uDC68\u200D\uD83D\uDC67\u200D\uD83D\uDC66") + } + + withAnimationView("Tests/DynamicText.json", "Dynamic Text", "Family woman woman girl girl") { animationView -> + val textDelegate = TextDelegate(animationView) + animationView.setTextDelegate(textDelegate) + textDelegate.setText("NAME", "\uD83D\uDC69\u200D\uD83D\uDC69\u200D\uD83D\uDC67\u200D\uD83D\uDC67") + } + + withAnimationView("Tests/DynamicText.json", "Dynamic Text", "Brown Police Man") { animationView -> + val textDelegate = TextDelegate(animationView) + animationView.setTextDelegate(textDelegate) + textDelegate.setText("NAME", "\uD83D\uDC6E\uD83C\uDFFF\u200D♀️") + } + + withAnimationView("Tests/DynamicText.json", "Dynamic Text", "Family and Brown Police Man") { animationView -> + val textDelegate = TextDelegate(animationView) + animationView.setTextDelegate(textDelegate) + textDelegate.setText("NAME", "\uD83D\uDC68\u200D\uD83D\uDC68\u200D\uD83D\uDC67\u200D\uD83D\uDC67\uD83D\uDC6E\uD83C\uDFFF\u200D♀️") + } + + withAnimationView("Tests/DynamicText.json", "Dynamic Text", "Family, Brown Police Man, emoji and chars") { animationView -> + val textDelegate = TextDelegate(animationView) + animationView.setTextDelegate(textDelegate) + textDelegate.setText("NAME", "🔥\uD83D\uDC68\u200D\uD83D\uDC68\u200D\uD83D\uDC67\u200D\uD83D\uDC67\uD83D\uDC6E\uD83C\uDFFF\u200D♀的Aabc️") + } + + withAnimationView("Tests/DynamicText.json", "Dynamic Text", "Fire English Fire Brown Police Man Fire") { animationView -> + val textDelegate = TextDelegate(animationView) + animationView.setTextDelegate(textDelegate) + textDelegate.setText("NAME", "🔥c️🔥\uD83D\uDC6E\uD83C\uDFFF\u200D♀️\uD83D\uDD25") + } + + withAnimationView("Tests/DynamicText.json", "Dynamic Text", "American Flag") { animationView -> + val textDelegate = TextDelegate(animationView) + animationView.setTextDelegate(textDelegate) + textDelegate.setText("NAME", "\uD83C\uDDFA\uD83C\uDDF8") + } + + withAnimationView("Tests/DynamicText.json", "Dynamic Text", "Checkered Flag") { animationView -> + val textDelegate = TextDelegate(animationView) + animationView.setTextDelegate(textDelegate) + textDelegate.setText("NAME", "\uD83C\uDFC1") + } + + withAnimationView("Tests/DynamicText.json", "Dynamic Text", "Pirate Flag") { animationView -> + val textDelegate = TextDelegate(animationView) + animationView.setTextDelegate(textDelegate) + textDelegate.setText("NAME", "\uD83C\uDFF4\u200D☠️") + } + + withAnimationView("Tests/DynamicText.json", "Dynamic Text", "3 Oclock") { animationView -> + val textDelegate = TextDelegate(animationView) + animationView.setTextDelegate(textDelegate) + textDelegate.setText("NAME", "\uD83D\uDD52") + } + + withAnimationView("Tests/DynamicText.json", "Dynamic Text", "Woman frowning") { animationView -> + val textDelegate = TextDelegate(animationView) + animationView.setTextDelegate(textDelegate) + textDelegate.setText("NAME", "\uD83D\uDE4D\u200D♀️") + } + + withAnimationView("Tests/DynamicText.json", "Dynamic Text", "Gay couple") { animationView -> + val textDelegate = TextDelegate(animationView) + animationView.setTextDelegate(textDelegate) + textDelegate.setText("NAME", "\uD83D\uDC68\u200D❤️\u200D\uD83D\uDC68️") + } + + withAnimationView("Tests/DynamicText.json", "Dynamic Text", "Lesbian couple") { animationView -> + val textDelegate = TextDelegate(animationView) + animationView.setTextDelegate(textDelegate) + textDelegate.setText("NAME", "\uD83D\uDC69\u200D❤️\u200D\uD83D\uDC69️") + } + + withAnimationView("Tests/DynamicText.json", "Dynamic Text", "Straight couple") { animationView -> + val textDelegate = TextDelegate(animationView) + animationView.setTextDelegate(textDelegate) + textDelegate.setText("NAME", "\uD83D\uDC91") } } diff --git a/sample/src/main/assets/Tests/DynamicText.json b/sample/src/main/assets/Tests/DynamicText.json index e97e284d1c..fad053c83f 100644 --- a/sample/src/main/assets/Tests/DynamicText.json +++ b/sample/src/main/assets/Tests/DynamicText.json @@ -1,950 +1,2 @@ -{ - "v": "4.8.0", - "fr": 29.9700012207031, - "ip": 0, - "op": 61.0000024845809, - "w": 150, - "h": 150, - "nm": "Name", - "ddd": 0, - "assets": [], - "fonts": { - "list": [ - { - "origin": 0, - "fPath": "", - "fClass": "", - "fFamily": "Comic Neue", - "fWeight": "", - "fStyle": "Regular", - "fName": "ComicNeue", - "ascent": 69.6990966796875 - } - ] - }, - "layers": [ - { - "ddd": 0, - "ind": 1, - "ty": 5, - "nm": "NAME", - "ks": { - "o": { - "a": 0, - "k": 100 - }, - "r": { - "a": 0, - "k": 0 - }, - "p": { - "a": 1, - "k": [ - { - "i": { - "x": 0.833, - "y": 0.833 - }, - "o": { - "x": 0.167, - "y": 0.167 - }, - "n": "0p833_0p833_0p167_0p167", - "t": 0, - "s": [ - 10.5, - 15, - 0 - ], - "e": [ - 10.5, - 147, - 0 - ], - "to": [ - 0, - 22, - 0 - ], - "ti": [ - 0, - 0, - 0 - ] - }, - { - "i": { - "x": 0.833, - "y": 0.833 - }, - "o": { - "x": 0.167, - "y": 0.167 - }, - "n": "0p833_0p833_0p167_0p167", - "t": 15, - "s": [ - 10.5, - 147, - 0 - ], - "e": [ - 10.5, - 15, - 0 - ], - "to": [ - 0, - 0, - 0 - ], - "ti": [ - 0, - 22, - 0 - ] - }, - { - "t": 30.0000012219251 - } - ] - }, - "a": { - "a": 0, - "k": [ - 0, - 0, - 0 - ] - }, - "s": { - "a": 1, - "k": [ - { - "i": { - "x": [ - 0.833, - 0.833, - 0.833 - ], - "y": [ - 0.833, - 0.833, - 0.833 - ] - }, - "o": { - "x": [ - 0.167, - 0.167, - 0.167 - ], - "y": [ - 0.167, - 0.167, - 0.167 - ] - }, - "n": [ - "0p833_0p833_0p167_0p167", - "0p833_0p833_0p167_0p167", - "0p833_0p833_0p167_0p167" - ], - "t": 0, - "s": [ - 100, - 100, - 100 - ], - "e": [ - 196, - 196, - 100 - ] - }, - { - "i": { - "x": [ - 0.833, - 0.833, - 0.833 - ], - "y": [ - 0.833, - 0.833, - 0.833 - ] - }, - "o": { - "x": [ - 0.167, - 0.167, - 0.167 - ], - "y": [ - 0.167, - 0.167, - 0.167 - ] - }, - "n": [ - "0p833_0p833_0p167_0p167", - "0p833_0p833_0p167_0p167", - "0p833_0p833_0p167_0p167" - ], - "t": 15, - "s": [ - 196, - 196, - 100 - ], - "e": [ - 100, - 100, - 100 - ] - }, - { - "t": 30.0000012219251 - } - ] - } - }, - "ao": 0, - "t": { - "d": { - "k": [ - { - "s": { - "s": 14, - "f": "ComicNeue", - "t": "NAME", - "j": 0, - "tr": 0, - "lh": 16.8, - "ls": 0, - "fc": [ - 0.92, - 0, - 0 - ] - }, - "t": 0 - } - ] - }, - "p": {}, - "m": { - "g": 1, - "a": { - "a": 0, - "k": [ - 0, - 0 - ] - } - }, - "a": [ - { - "s": { - "t": 0, - "xe": { - "a": 0, - "k": 0 - }, - "ne": { - "a": 0, - "k": 0 - }, - "a": { - "a": 0, - "k": 100 - }, - "b": 1, - "rn": 0, - "sh": 1, - "r": 1 - }, - "a": { - "fc": { - "a": 1, - "k": [ - { - "i": { - "x": [ - 0.833 - ], - "y": [ - 0.833 - ] - }, - "o": { - "x": [ - 0.167 - ], - "y": [ - 0.167 - ] - }, - "n": [ - "0p833_0p833_0p167_0p167" - ], - "t": 0, - "s": [ - 1, - 0, - 0, - 1 - ], - "e": [ - 0, - 1, - 0, - 1 - ] - }, - { - "i": { - "x": [ - 0.833 - ], - "y": [ - 0.833 - ] - }, - "o": { - "x": [ - 0.167 - ], - "y": [ - 0.167 - ] - }, - "n": [ - "0p833_0p833_0p167_0p167" - ], - "t": 15, - "s": [ - 0, - 1, - 0, - 1 - ], - "e": [ - 0, - 0, - 1, - 1 - ] - }, - { - "i": { - "x": [ - 0.833 - ], - "y": [ - 0.833 - ] - }, - "o": { - "x": [ - 0.167 - ], - "y": [ - 0.167 - ] - }, - "n": [ - "0p833_0p833_0p167_0p167" - ], - "t": 30, - "s": [ - 0, - 0, - 1, - 1 - ], - "e": [ - 0, - 1, - 0, - 1 - ] - }, - { - "i": { - "x": [ - 0.833 - ], - "y": [ - 0.833 - ] - }, - "o": { - "x": [ - 0.167 - ], - "y": [ - 0.167 - ] - }, - "n": [ - "0p833_0p833_0p167_0p167" - ], - "t": 45, - "s": [ - 0, - 1, - 0, - 1 - ], - "e": [ - 1, - 0, - 0, - 1 - ] - }, - { - "t": 60.0000024438501 - } - ] - }, - "t": { - "a": 1, - "k": [ - { - "i": { - "x": [ - 0.833 - ], - "y": [ - 0.833 - ] - }, - "o": { - "x": [ - 0.167 - ], - "y": [ - 0.167 - ] - }, - "n": [ - "0p833_0p833_0p167_0p167" - ], - "t": 30, - "s": [ - 0 - ], - "e": [ - 20 - ] - }, - { - "i": { - "x": [ - 0.833 - ], - "y": [ - 0.833 - ] - }, - "o": { - "x": [ - 0.167 - ], - "y": [ - 0.167 - ] - }, - "n": [ - "0p833_0p833_0p167_0p167" - ], - "t": 45, - "s": [ - 20 - ], - "e": [ - 0 - ] - }, - { - "t": 60.0000024438501 - } - ] - } - } - } - ] - }, - "ip": 0, - "op": 61.0000024845809, - "st": 0, - "bm": 0, - "sr": 1 - }, - { - "ddd": 0, - "ind": 1, - "ty": 5, - "nm": "Name Not matching Text", - "ks": { - "o": { - "a": 0, - "k": 100 - }, - "r": { - "a": 0, - "k": 0 - }, - "p": { - "a": 1, - "k": [ - { - "i": { - "x": 0.833, - "y": 0.833 - }, - "o": { - "x": 0.167, - "y": 0.167 - }, - "n": "0p833_0p833_0p167_0p167", - "t": 0, - "s": [ - 10.5, - 15, - 0 - ], - "e": [ - 10.5, - 147, - 0 - ], - "to": [ - 0, - 22, - 0 - ], - "ti": [ - 0, - 0, - 0 - ] - }, - { - "i": { - "x": 0.833, - "y": 0.833 - }, - "o": { - "x": 0.167, - "y": 0.167 - }, - "n": "0p833_0p833_0p167_0p167", - "t": 15, - "s": [ - 10.5, - 147, - 0 - ], - "e": [ - 10.5, - 15, - 0 - ], - "to": [ - 0, - 0, - 0 - ], - "ti": [ - 0, - 22, - 0 - ] - }, - { - "t": 30.0000012219251 - } - ] - }, - "a": { - "a": 0, - "k": [ - 0, - 0, - 0 - ] - }, - "s": { - "a": 1, - "k": [ - { - "i": { - "x": [ - 0.833, - 0.833, - 0.833 - ], - "y": [ - 0.833, - 0.833, - 0.833 - ] - }, - "o": { - "x": [ - 0.167, - 0.167, - 0.167 - ], - "y": [ - 0.167, - 0.167, - 0.167 - ] - }, - "n": [ - "0p833_0p833_0p167_0p167", - "0p833_0p833_0p167_0p167", - "0p833_0p833_0p167_0p167" - ], - "t": 0, - "s": [ - 100, - 100, - 100 - ], - "e": [ - 196, - 196, - 100 - ] - }, - { - "i": { - "x": [ - 0.833, - 0.833, - 0.833 - ], - "y": [ - 0.833, - 0.833, - 0.833 - ] - }, - "o": { - "x": [ - 0.167, - 0.167, - 0.167 - ], - "y": [ - 0.167, - 0.167, - 0.167 - ] - }, - "n": [ - "0p833_0p833_0p167_0p167", - "0p833_0p833_0p167_0p167", - "0p833_0p833_0p167_0p167" - ], - "t": 15, - "s": [ - 196, - 196, - 100 - ], - "e": [ - 100, - 100, - 100 - ] - }, - { - "t": 30.0000012219251 - } - ] - } - }, - "ao": 0, - "t": { - "d": { - "k": [ - { - "s": { - "s": 14, - "f": "ComicNeue", - "t": "NAME", - "j": 0, - "tr": 0, - "lh": 16.8, - "ls": 0, - "fc": [ - 0.92, - 0, - 0 - ] - }, - "t": 0 - } - ] - }, - "p": {}, - "m": { - "g": 1, - "a": { - "a": 0, - "k": [ - 0, - 0 - ] - } - }, - "a": [ - { - "s": { - "t": 0, - "xe": { - "a": 0, - "k": 0 - }, - "ne": { - "a": 0, - "k": 0 - }, - "a": { - "a": 0, - "k": 100 - }, - "b": 1, - "rn": 0, - "sh": 1, - "r": 1 - }, - "a": { - "fc": { - "a": 1, - "k": [ - { - "i": { - "x": [ - 0.833 - ], - "y": [ - 0.833 - ] - }, - "o": { - "x": [ - 0.167 - ], - "y": [ - 0.167 - ] - }, - "n": [ - "0p833_0p833_0p167_0p167" - ], - "t": 0, - "s": [ - 1, - 0, - 0, - 1 - ], - "e": [ - 0, - 1, - 0, - 1 - ] - }, - { - "i": { - "x": [ - 0.833 - ], - "y": [ - 0.833 - ] - }, - "o": { - "x": [ - 0.167 - ], - "y": [ - 0.167 - ] - }, - "n": [ - "0p833_0p833_0p167_0p167" - ], - "t": 15, - "s": [ - 0, - 1, - 0, - 1 - ], - "e": [ - 0, - 0, - 1, - 1 - ] - }, - { - "i": { - "x": [ - 0.833 - ], - "y": [ - 0.833 - ] - }, - "o": { - "x": [ - 0.167 - ], - "y": [ - 0.167 - ] - }, - "n": [ - "0p833_0p833_0p167_0p167" - ], - "t": 30, - "s": [ - 0, - 0, - 1, - 1 - ], - "e": [ - 0, - 1, - 0, - 1 - ] - }, - { - "i": { - "x": [ - 0.833 - ], - "y": [ - 0.833 - ] - }, - "o": { - "x": [ - 0.167 - ], - "y": [ - 0.167 - ] - }, - "n": [ - "0p833_0p833_0p167_0p167" - ], - "t": 45, - "s": [ - 0, - 1, - 0, - 1 - ], - "e": [ - 1, - 0, - 0, - 1 - ] - }, - { - "t": 60.0000024438501 - } - ] - }, - "t": { - "a": 1, - "k": [ - { - "i": { - "x": [ - 0.833 - ], - "y": [ - 0.833 - ] - }, - "o": { - "x": [ - 0.167 - ], - "y": [ - 0.167 - ] - }, - "n": [ - "0p833_0p833_0p167_0p167" - ], - "t": 30, - "s": [ - 0 - ], - "e": [ - 20 - ] - }, - { - "i": { - "x": [ - 0.833 - ], - "y": [ - 0.833 - ] - }, - "o": { - "x": [ - 0.167 - ], - "y": [ - 0.167 - ] - }, - "n": [ - "0p833_0p833_0p167_0p167" - ], - "t": 45, - "s": [ - 20 - ], - "e": [ - 0 - ] - }, - { - "t": 60.0000024438501 - } - ] - } - } - } - ] - }, - "ip": 0, - "op": 61.0000024845809, - "st": 0, - "bm": 0, - "sr": 1 - } - - ] -} \ No newline at end of file +{"v":"4.8.0","fr":29.9700012207031,"ip":0,"op":61.0000024845809,"w":150,"h":150,"nm":"Name", + "ddd":0,"assets":[],"fonts":{"list":[{"origin":0,"fPath":"","fClass":"","fFamily":"Comic Neue","fWeight":"","fStyle":"Regular","fName":"ComicNeue","ascent":69.6990966796875}]},"layers":[{"ddd":0,"ind":1,"ty":5,"nm":"NAME","ks":{"o":{"a":0,"k":100},"r":{"a":0,"k":0},"p":{"a":1,"k":[{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":0,"s":[10.5,15,0],"e":[10.5,147,0],"to":[0,22,0],"ti":[0,0,0]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":15,"s":[10.5,147,0],"e":[10.5,15,0],"to":[0,0,0],"ti":[0,22,0]},{"t":30.0000012219251}]},"a":{"a":0,"k":[0,0,0]},"s":{"a":1,"k":[{"i":{"x":[0.833,0.833,0.833],"y":[0.833,0.833,0.833]},"o":{"x":[0.167,0.167,0.167],"y":[0.167,0.167,0.167]},"n":["0p833_0p833_0p167_0p167","0p833_0p833_0p167_0p167","0p833_0p833_0p167_0p167"],"t":0,"s":[100,100,100],"e":[196,196,100]},{"i":{"x":[0.833,0.833,0.833],"y":[0.833,0.833,0.833]},"o":{"x":[0.167,0.167,0.167],"y":[0.167,0.167,0.167]},"n":["0p833_0p833_0p167_0p167","0p833_0p833_0p167_0p167","0p833_0p833_0p167_0p167"],"t":15,"s":[196,196,100],"e":[100,100,100]},{"t":30.0000012219251}]}},"ao":0,"t":{"d":{"k":[{"s":{"s":14,"f":"ComicNeue","t":"NAME","j":0,"tr":0,"lh":16.8,"ls":0,"fc":[0.92,0,0]},"t":0}]},"p":{},"m":{"g":1,"a":{"a":0,"k":[0,0]}},"a":[{"s":{"t":0,"xe":{"a":0,"k":0},"ne":{"a":0,"k":0},"a":{"a":0,"k":100},"b":1,"rn":0,"sh":1,"r":1},"a":{"fc":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":0,"s":[1,0,0,1],"e":[0,1,0,1]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":15,"s":[0,1,0,1],"e":[0,0,1,1]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":30,"s":[0,0,1,1],"e":[0,1,0,1]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":45,"s":[0,1,0,1],"e":[1,0,0,1]},{"t":60.0000024438501}]},"t":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":30,"s":[0],"e":[20]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":45,"s":[20],"e":[0]},{"t":60.0000024438501}]}}}]},"ip":0,"op":61.0000024845809,"st":0,"bm":0,"sr":1}]} \ No newline at end of file From c5ea9b43723e6154e81cc4a641d3f3ad5130dca2 Mon Sep 17 00:00:00 2001 From: Greg Giacovelli Date: Fri, 22 Oct 2021 09:08:55 -0700 Subject: [PATCH 3/5] Moving to using keyPathName as string to reduce allocations and be more consistent with iOS --- lottie/src/main/java/com/airbnb/lottie/TextDelegate.java | 8 ++++---- .../java/com/airbnb/lottie/model/layer/TextLayer.java | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/lottie/src/main/java/com/airbnb/lottie/TextDelegate.java b/lottie/src/main/java/com/airbnb/lottie/TextDelegate.java index 31d80c08d6..91a663ca97 100644 --- a/lottie/src/main/java/com/airbnb/lottie/TextDelegate.java +++ b/lottie/src/main/java/com/airbnb/lottie/TextDelegate.java @@ -47,11 +47,11 @@ public TextDelegate(@SuppressWarnings("NullableProblems") LottieDrawable drawabl /** * Override this to replace the animation text with something dynamic. This can be used for * translations or custom data. - * @param path the name of the layer with text + * @param keyPathName the name of the layer with text * @param input the string at the layer with text * @return a String to use for the specific data, by default this is the same as getText(input) */ - public String getText(KeyPath path, String input) { + public String getText(String keyPathName, String input) { return getText(input); } @@ -96,11 +96,11 @@ public void invalidateAllText() { } @RestrictTo(RestrictTo.Scope.LIBRARY) - public final String getTextInternal(KeyPath path, String input) { + public final String getTextInternal(String keyPathName, String input) { if (cacheText && stringMap.containsKey(input)) { return stringMap.get(input); } - String text = getText(path, input); + String text = getText(keyPathName, input); if (cacheText) { stringMap.put(input, text); } 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 5b959ecad2..d67e9cb1d9 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 @@ -246,7 +246,7 @@ private void drawTextWithFont( String text = documentData.text; TextDelegate textDelegate = lottieDrawable.getTextDelegate(); if (textDelegate != null) { - text = textDelegate.getTextInternal(new KeyPath(getName()), text); + text = textDelegate.getTextInternal(getName(), text); } fillPaint.setTypeface(typeface); float textSize; From 52e1a29652839b376f1b1e41c4c516a1abb3d2a5 Mon Sep 17 00:00:00 2001 From: Greg Giacovelli Date: Fri, 22 Oct 2021 09:10:02 -0700 Subject: [PATCH 4/5] Closes #1932 Adds context of keyPathName to TextDelegate and be more consistent with iOS --- lottie/src/main/java/com/airbnb/lottie/TextDelegate.java | 2 -- 1 file changed, 2 deletions(-) diff --git a/lottie/src/main/java/com/airbnb/lottie/TextDelegate.java b/lottie/src/main/java/com/airbnb/lottie/TextDelegate.java index 91a663ca97..7210e74179 100644 --- a/lottie/src/main/java/com/airbnb/lottie/TextDelegate.java +++ b/lottie/src/main/java/com/airbnb/lottie/TextDelegate.java @@ -4,8 +4,6 @@ import androidx.annotation.RestrictTo; import androidx.annotation.VisibleForTesting; -import com.airbnb.lottie.model.KeyPath; - import java.util.HashMap; import java.util.Map; From 2099504f2026280a47f934b702fb21403d14690f Mon Sep 17 00:00:00 2001 From: Greg Giacovelli Date: Tue, 2 Nov 2021 13:04:23 -0700 Subject: [PATCH 5/5] Use layer name instead of keypathName --- lottie/src/main/java/com/airbnb/lottie/TextDelegate.java | 8 ++++---- .../java/com/airbnb/lottie/model/layer/TextLayer.java | 1 - 2 files changed, 4 insertions(+), 5 deletions(-) diff --git a/lottie/src/main/java/com/airbnb/lottie/TextDelegate.java b/lottie/src/main/java/com/airbnb/lottie/TextDelegate.java index 7210e74179..f9a2a67785 100644 --- a/lottie/src/main/java/com/airbnb/lottie/TextDelegate.java +++ b/lottie/src/main/java/com/airbnb/lottie/TextDelegate.java @@ -45,11 +45,11 @@ public TextDelegate(@SuppressWarnings("NullableProblems") LottieDrawable drawabl /** * Override this to replace the animation text with something dynamic. This can be used for * translations or custom data. - * @param keyPathName the name of the layer with text + * @param layerName the name of the layer with text * @param input the string at the layer with text * @return a String to use for the specific data, by default this is the same as getText(input) */ - public String getText(String keyPathName, String input) { + public String getText(String layerName, String input) { return getText(input); } @@ -94,11 +94,11 @@ public void invalidateAllText() { } @RestrictTo(RestrictTo.Scope.LIBRARY) - public final String getTextInternal(String keyPathName, String input) { + public final String getTextInternal(String layerName, String input) { if (cacheText && stringMap.containsKey(input)) { return stringMap.get(input); } - String text = getText(keyPathName, input); + String text = getText(layerName, input); if (cacheText) { stringMap.put(input, text); } 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 d67e9cb1d9..db931411b4 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 @@ -23,7 +23,6 @@ import com.airbnb.lottie.model.DocumentData.Justification; import com.airbnb.lottie.model.Font; import com.airbnb.lottie.model.FontCharacter; -import com.airbnb.lottie.model.KeyPath; import com.airbnb.lottie.model.animatable.AnimatableTextProperties; import com.airbnb.lottie.model.content.ShapeGroup; import com.airbnb.lottie.utils.Utils;