Automatically reuse tasks for in-progress parses (#887)
Previously, if you tried to parse the same animation multiple times in parallel, it would start a new parse unless the first one completed and was cached. Now, Lottie will retain in-progress tasks so it will just join the first task for that animation.
diff --git a/LottieSample/build.gradle b/LottieSample/build.gradle
index 30d8670..2097abe 100644
--- a/LottieSample/build.gradle
+++ b/LottieSample/build.gradle
@@ -61,8 +61,8 @@
implementation 'android.arch.lifecycle:extensions:1.1.0'
kapt "android.arch.lifecycle:compiler:1.1.0"
implementation "com.android.support:customtabs:$supportLibVersion"
- implementation 'com.airbnb.android:epoxy:2.10.0'
- kapt 'com.airbnb.android:epoxy-processor:2.10.0'
+ implementation 'com.airbnb.android:epoxy:2.16.1'
+ kapt 'com.airbnb.android:epoxy-processor:2.16.1'
implementation 'com.android.support.constraint:constraint-layout:1.1.0-beta5'
implementation 'androidx.core:core-ktx:0.2'
implementation "org.jetbrains.kotlin:kotlin-stdlib:$kotlinVersion"
diff --git a/LottieSample/src/main/AndroidManifest.xml b/LottieSample/src/main/AndroidManifest.xml
index fbaa03f..1a7f6bc 100644
--- a/LottieSample/src/main/AndroidManifest.xml
+++ b/LottieSample/src/main/AndroidManifest.xml
@@ -59,8 +59,8 @@
android:host="*"/>
</intent-filter>
</activity>
- <activity android:name=".DynamicTextActivity">
- </activity>
+ <activity android:name=".DynamicTextActivity" />
+ <activity android:name=".ListActivity" />
</application>
</manifest>
\ No newline at end of file
diff --git a/LottieSample/src/main/kotlin/com/airbnb/lottie/samples/ListActivity.kt b/LottieSample/src/main/kotlin/com/airbnb/lottie/samples/ListActivity.kt
new file mode 100644
index 0000000..cbfa463
--- /dev/null
+++ b/LottieSample/src/main/kotlin/com/airbnb/lottie/samples/ListActivity.kt
@@ -0,0 +1,39 @@
+package com.airbnb.lottie.samples
+
+import android.os.Bundle
+import android.support.v7.app.AppCompatActivity
+import com.airbnb.epoxy.EpoxyController
+import com.airbnb.lottie.samples.views.ListingCard
+import com.airbnb.lottie.samples.views.WishListIconView
+import com.airbnb.lottie.samples.views.listingCard
+import com.airbnb.lottie.samples.views.marquee
+import kotlinx.android.synthetic.main.activity_list.*
+
+class ListActivity : AppCompatActivity() {
+
+ override fun onCreate(savedInstanceState: Bundle?) {
+ super.onCreate(savedInstanceState)
+ setContentView(R.layout.activity_list)
+
+ setSupportActionBar(toolbar)
+ supportActionBar?.setDisplayShowTitleEnabled(false)
+ toolbar.setNavigationOnClickListener { finish() }
+
+ recyclerView.buildModelsWith { it.buildModels() }
+ }
+
+ private fun EpoxyController.buildModels() {
+ marquee {
+ id("marquee")
+ title("List")
+ subtitle("Loading the same animation many times in a list")
+ }
+
+ repeat(100) {
+ listingCard {
+ id(it)
+ clickListener { view -> (view as WishListIconView).toggleWishlisted() }
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/LottieSample/src/main/kotlin/com/airbnb/lottie/samples/ShowcaseFragment.kt b/LottieSample/src/main/kotlin/com/airbnb/lottie/samples/ShowcaseFragment.kt
index 88a0397..f3fa425 100644
--- a/LottieSample/src/main/kotlin/com/airbnb/lottie/samples/ShowcaseFragment.kt
+++ b/LottieSample/src/main/kotlin/com/airbnb/lottie/samples/ShowcaseFragment.kt
@@ -35,6 +35,9 @@
},
ShowcaseItem(R.drawable.showcase_preview_lottie, R.string.showcase_item_bullseye) {
startActivity(Intent(requireContext(), BullseyeActivity::class.java))
+ },
+ ShowcaseItem(R.drawable.showcase_preview_lottie, R.string.showcase_item_recycler_viwe) {
+ startActivity(Intent(requireContext(), ListActivity::class.java))
}
)
private val viewModel by lazy { ViewModelProviders.of(this).get(ShowcaseViewModel::class.java) }
diff --git a/LottieSample/src/main/kotlin/com/airbnb/lottie/samples/views/ListingCard.kt b/LottieSample/src/main/kotlin/com/airbnb/lottie/samples/views/ListingCard.kt
new file mode 100644
index 0000000..8191327
--- /dev/null
+++ b/LottieSample/src/main/kotlin/com/airbnb/lottie/samples/views/ListingCard.kt
@@ -0,0 +1,26 @@
+package com.airbnb.lottie.samples.views
+
+import android.content.Context
+import android.util.AttributeSet
+import android.view.View
+import android.widget.FrameLayout
+import com.airbnb.epoxy.CallbackProp
+import com.airbnb.epoxy.ModelProp
+import com.airbnb.epoxy.ModelView
+import com.airbnb.lottie.samples.R
+import kotlinx.android.synthetic.main.listing_card.view.*
+
+@ModelView(autoLayout = ModelView.Size.MATCH_WIDTH_WRAP_HEIGHT)
+class ListingCard @JvmOverloads constructor(
+ context: Context, attrs: AttributeSet? = null, defStyleAttr: Int = 0
+) : FrameLayout(context, attrs, defStyleAttr) {
+
+ init {
+ inflate(context, R.layout.listing_card, this)
+ }
+
+ @CallbackProp
+ fun setClickListener(listener: View.OnClickListener?) {
+ wishListIcon.setOnClickListener(listener)
+ }
+}
\ No newline at end of file
diff --git a/LottieSample/src/main/kotlin/com/airbnb/lottie/samples/views/WishListIconView.kt b/LottieSample/src/main/kotlin/com/airbnb/lottie/samples/views/WishListIconView.kt
new file mode 100644
index 0000000..a741cd9
--- /dev/null
+++ b/LottieSample/src/main/kotlin/com/airbnb/lottie/samples/views/WishListIconView.kt
@@ -0,0 +1,24 @@
+package com.airbnb.lottie.samples.views
+
+import android.content.Context
+import android.util.AttributeSet
+import com.airbnb.epoxy.ModelProp
+import com.airbnb.epoxy.ModelView
+import com.airbnb.lottie.LottieAnimationView
+import kotlinx.android.synthetic.main.listing_card.view.*
+
+class WishListIconView @JvmOverloads constructor(
+ context: Context, attrs: AttributeSet? = null, defStyleAttr: Int = 0
+) : LottieAnimationView(context, attrs, defStyleAttr) {
+
+ fun toggleWishlisted() {
+ isActivated = !isActivated
+ }
+
+ override fun setActivated(activated: Boolean) {
+ super.setActivated(activated)
+ speed = if (activated) 1f else -2f
+ progress = 0f
+ playAnimation()
+ }
+}
\ No newline at end of file
diff --git a/LottieSample/src/main/res/layout/activity_list.xml b/LottieSample/src/main/res/layout/activity_list.xml
new file mode 100644
index 0000000..551f4df
--- /dev/null
+++ b/LottieSample/src/main/res/layout/activity_list.xml
@@ -0,0 +1,18 @@
+<?xml version="1.0" encoding="utf-8"?>
+<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:app="http://schemas.android.com/apk/res-auto"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent">
+
+ <com.airbnb.epoxy.EpoxyRecyclerView
+ android:id="@+id/recyclerView"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"/>
+
+ <android.support.v7.widget.Toolbar
+ android:id="@+id/toolbar"
+ android:layout_width="match_parent"
+ android:layout_height="?attr/actionBarSize"
+ app:navigationIcon="@drawable/ic_back_black"/>
+
+</FrameLayout>
\ No newline at end of file
diff --git a/LottieSample/src/main/res/layout/listing_card.xml b/LottieSample/src/main/res/layout/listing_card.xml
new file mode 100644
index 0000000..f601643
--- /dev/null
+++ b/LottieSample/src/main/res/layout/listing_card.xml
@@ -0,0 +1,27 @@
+<?xml version="1.0" encoding="utf-8"?>
+<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:app="http://schemas.android.com/apk/res-auto"
+ xmlns:tools="http://schemas.android.com/tools"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content">
+
+ <View
+ android:id="@+id/image"
+ android:layout_width="match_parent"
+ android:layout_height="72dp"
+ android:background="@color/loading_placeholder"
+ android:layout_marginLeft="@dimen/activity_horizontal_margin"
+ android:layout_marginRight="@dimen/activity_horizontal_margin"
+ android:layout_marginBottom="16dp"/>
+
+ <com.airbnb.lottie.samples.views.WishListIconView
+ android:id="@+id/wishListIcon"
+ android:layout_width="96dp"
+ android:layout_height="96dp"
+ android:layout_marginTop="-16dp"
+ android:layout_alignParentTop="true"
+ android:layout_alignParentRight="true"
+ app:lottie_rawRes="@raw/heart"
+ android:scaleType="centerCrop"/>
+
+</RelativeLayout>
\ No newline at end of file
diff --git a/LottieSample/src/main/res/raw/heart.json b/LottieSample/src/main/res/raw/heart.json
new file mode 100755
index 0000000..48fa0ec
--- /dev/null
+++ b/LottieSample/src/main/res/raw/heart.json
@@ -0,0 +1 @@
+{"v":"4.11.1","fr":60,"ip":0,"op":116,"w":50,"h":50,"nm":"TwitterHeart","ddd":0,"assets":[],"layers":[{"ddd":0,"ind":1,"ty":4,"nm":"Dot14","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":-320,"ix":10},"p":{"a":0,"k":[25,25,0],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[40,40,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0]],"o":[[0,0],[0,0]],"v":[[-37.5,-40.5],[-1,0.5]],"c":false},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"tm","s":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":44,"s":[47],"e":[29]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":56,"s":[29],"e":[9]},{"t":78}],"ix":1},"e":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":44,"s":[48],"e":[30]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":56,"s":[30],"e":[10]},{"t":78}],"ix":2},"o":{"a":0,"k":0,"ix":3},"m":1,"ix":2,"nm":"Trim Paths 1","mn":"ADBE Vector Filter - Trim","hd":false},{"ty":"st","c":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":44,"s":[0.631372570992,0.811764717102,0.937254905701,1],"e":[0.819607853889,0.647058844566,0.909803926945,1]},{"t":56}],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":44,"s":[5],"e":[2]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":56,"s":[2],"e":[0]},{"t":70}],"ix":5},"lc":2,"lj":1,"ml":4,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Shape 1","np":3,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":44,"op":90,"st":-44,"bm":0},{"ddd":0,"ind":2,"ty":4,"nm":"Dot13","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":-306.6,"ix":10},"p":{"a":0,"k":[25,25,0],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[40,40,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0]],"o":[[0,0],[0,0]],"v":[[-37.5,-40.5],[-1,0.5]],"c":false},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"tm","s":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":44,"s":[44],"e":[19]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":56,"s":[19],"e":[0]},{"t":89}],"ix":1},"e":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":44,"s":[45],"e":[20]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":56,"s":[20],"e":[1]},{"t":89}],"ix":2},"o":{"a":0,"k":0,"ix":3},"m":1,"ix":2,"nm":"Trim Paths 1","mn":"ADBE Vector Filter - Trim","hd":false},{"ty":"st","c":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":44,"s":[0.658823549747,0.800000011921,0.96862745285,1],"e":[0.815686285496,0.654901981354,0.905882358551,1]},{"t":56}],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":56,"s":[5],"e":[0]},{"t":89}],"ix":5},"lc":2,"lj":1,"ml":4,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Shape 1","np":3,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":44,"op":90,"st":-44,"bm":0},{"ddd":0,"ind":3,"ty":4,"nm":"Dot12","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":-271.7,"ix":10},"p":{"a":0,"k":[25,25,0],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[40,40,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0]],"o":[[0,0],[0,0]],"v":[[-37.5,-40.5],[-1,0.5]],"c":false},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"tm","s":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":44,"s":[47],"e":[29]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":56,"s":[29],"e":[9]},{"t":78}],"ix":1},"e":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":44,"s":[48],"e":[30]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":56,"s":[30],"e":[10]},{"t":78}],"ix":2},"o":{"a":0,"k":0,"ix":3},"m":1,"ix":2,"nm":"Trim Paths 1","mn":"ADBE Vector Filter - Trim","hd":false},{"ty":"st","c":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":44,"s":[0.784313738346,0.588235318661,0.901960790157,1],"e":[0.890196084976,0.819607853889,0.580392181873,1]},{"t":56}],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":44,"s":[5],"e":[2]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":56,"s":[2],"e":[0]},{"t":70}],"ix":5},"lc":2,"lj":1,"ml":4,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Shape 1","np":3,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":44,"op":90,"st":-44,"bm":0},{"ddd":0,"ind":4,"ty":4,"nm":"Dot11","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":-258.3,"ix":10},"p":{"a":0,"k":[25,25,0],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[40,40,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0]],"o":[[0,0],[0,0]],"v":[[-37.5,-40.5],[-1,0.5]],"c":false},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"tm","s":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":44,"s":[44],"e":[19]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":56,"s":[19],"e":[0]},{"t":89}],"ix":1},"e":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":44,"s":[45],"e":[20]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":56,"s":[20],"e":[1]},{"t":89}],"ix":2},"o":{"a":0,"k":0,"ix":3},"m":1,"ix":2,"nm":"Trim Paths 1","mn":"ADBE Vector Filter - Trim","hd":false},{"ty":"st","c":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":44,"s":[0.784313738346,0.61960786581,0.89411765337,1],"e":[0.921568632126,0.749019622803,0.32549020648,1]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":56,"s":[0.921568632126,0.749019622803,0.32549020648,1],"e":[0.549019634724,0.274509817362,0.709803938866,1]},{"t":66}],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":56,"s":[5],"e":[0]},{"t":89}],"ix":5},"lc":2,"lj":1,"ml":4,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Shape 1","np":3,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":44,"op":90,"st":-44,"bm":0},{"ddd":0,"ind":5,"ty":4,"nm":"Dot10","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":-220.3,"ix":10},"p":{"a":0,"k":[25,25,0],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[40,40,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0]],"o":[[0,0],[0,0]],"v":[[-37.5,-40.5],[-1,0.5]],"c":false},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"tm","s":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":44,"s":[47],"e":[29]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":56,"s":[29],"e":[9]},{"t":78}],"ix":1},"e":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":44,"s":[48],"e":[30]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":56,"s":[30],"e":[10]},{"t":78}],"ix":2},"o":{"a":0,"k":0,"ix":3},"m":1,"ix":2,"nm":"Trim Paths 1","mn":"ADBE Vector Filter - Trim","hd":false},{"ty":"st","c":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":44,"s":[0.607843160629,0.886274516582,0.78823530674,1],"e":[0.792156875134,0.737254917622,0.600000023842,1]},{"t":56}],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":44,"s":[5],"e":[2]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":56,"s":[2],"e":[0]},{"t":70}],"ix":5},"lc":2,"lj":1,"ml":4,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Shape 1","np":3,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":44,"op":90,"st":-44,"bm":0},{"ddd":0,"ind":6,"ty":4,"nm":"Dot9","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":-206.9,"ix":10},"p":{"a":0,"k":[25,25,0],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[40,40,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0]],"o":[[0,0],[0,0]],"v":[[-37.5,-40.5],[-1,0.5]],"c":false},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"tm","s":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":44,"s":[44],"e":[19]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":56,"s":[19],"e":[0]},{"t":89}],"ix":1},"e":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":44,"s":[45],"e":[20]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":56,"s":[20],"e":[1]},{"t":89}],"ix":2},"o":{"a":0,"k":0,"ix":3},"m":1,"ix":2,"nm":"Trim Paths 1","mn":"ADBE Vector Filter - Trim","hd":false},{"ty":"st","c":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":44,"s":[0.61960786581,0.882352948189,0.780392169952,1],"e":[0.792156875134,0.737254917622,0.600000023842,1]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":56,"s":[0.792156875134,0.737254917622,0.600000023842,1],"e":[0.549019634724,0.274509817362,0.709803938866,1]},{"t":66}],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":56,"s":[5],"e":[0]},{"t":89}],"ix":5},"lc":2,"lj":1,"ml":4,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"tm","s":{"a":0,"k":44,"ix":1},"e":{"a":0,"k":45,"ix":2},"o":{"a":0,"k":0,"ix":3},"m":1,"ix":4,"nm":"Trim Paths 2","mn":"ADBE Vector Filter - Trim","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Shape 1","np":4,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":44,"op":90,"st":-44,"bm":0},{"ddd":0,"ind":7,"ty":4,"nm":"Dot8","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":-168.2,"ix":10},"p":{"a":0,"k":[25,25,0],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[40,40,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0]],"o":[[0,0],[0,0]],"v":[[-37.5,-40.5],[-1,0.5]],"c":false},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"tm","s":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":44,"s":[47],"e":[29]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":56,"s":[29],"e":[9]},{"t":78}],"ix":1},"e":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":44,"s":[48],"e":[30]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":56,"s":[30],"e":[10]},{"t":78}],"ix":2},"o":{"a":0,"k":0,"ix":3},"m":1,"ix":2,"nm":"Trim Paths 1","mn":"ADBE Vector Filter - Trim","hd":false},{"ty":"st","c":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":44,"s":[0.858823537827,0.623529434204,0.68235296011,1],"e":[0.329411774874,0.596078455448,0.800000011921,1]},{"t":56}],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":44,"s":[5],"e":[2]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":56,"s":[2],"e":[0]},{"t":70}],"ix":5},"lc":2,"lj":1,"ml":4,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Shape 1","np":3,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":44,"op":90,"st":-44,"bm":0},{"ddd":0,"ind":8,"ty":4,"nm":"Dot7","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":-154.8,"ix":10},"p":{"a":0,"k":[25,25,0],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[40,40,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0]],"o":[[0,0],[0,0]],"v":[[-37.5,-40.5],[-1,0.5]],"c":false},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"tm","s":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":44,"s":[44],"e":[19]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":56,"s":[19],"e":[0]},{"t":89}],"ix":1},"e":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":44,"s":[45],"e":[20]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":56,"s":[20],"e":[1]},{"t":89}],"ix":2},"o":{"a":0,"k":0,"ix":3},"m":1,"ix":2,"nm":"Trim Paths 1","mn":"ADBE Vector Filter - Trim","hd":false},{"ty":"st","c":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":44,"s":[0.890196084976,0.600000023842,0.694117665291,1],"e":[0.329411774874,0.596078455448,0.800000011921,1]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":56,"s":[0.329411774874,0.596078455448,0.800000011921,1],"e":[0.549019634724,0.274509817362,0.709803938866,1]},{"t":66}],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":56,"s":[5],"e":[0]},{"t":89}],"ix":5},"lc":2,"lj":1,"ml":4,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Shape 1","np":3,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":44,"op":90,"st":-44,"bm":0},{"ddd":0,"ind":9,"ty":4,"nm":"Dot6","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":-117.1,"ix":10},"p":{"a":0,"k":[25,25,0],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[40,40,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0]],"o":[[0,0],[0,0]],"v":[[-37.5,-40.5],[-1,0.5]],"c":false},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"tm","s":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":44,"s":[47],"e":[29]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":56,"s":[29],"e":[9]},{"t":78}],"ix":1},"e":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":44,"s":[48],"e":[30]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":56,"s":[30],"e":[10]},{"t":78}],"ix":2},"o":{"a":0,"k":0,"ix":3},"m":1,"ix":2,"nm":"Trim Paths 1","mn":"ADBE Vector Filter - Trim","hd":false},{"ty":"st","c":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":44,"s":[0.61960786581,0.815686285496,0.956862747669,1],"e":[0.701960802078,0.843137264252,0.658823549747,1]},{"t":56}],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":44,"s":[5],"e":[2]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":56,"s":[2],"e":[0]},{"t":70}],"ix":5},"lc":2,"lj":1,"ml":4,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"tm","s":{"a":0,"k":29,"ix":1},"e":{"a":0,"k":30,"ix":2},"o":{"a":0,"k":0,"ix":3},"m":1,"ix":4,"nm":"Trim Paths 2","mn":"ADBE Vector Filter - Trim","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Shape 1","np":4,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":44,"op":90,"st":-44,"bm":0},{"ddd":0,"ind":10,"ty":4,"nm":"Dot5","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":-103.7,"ix":10},"p":{"a":0,"k":[25,25,0],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[40,40,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0]],"o":[[0,0],[0,0]],"v":[[-37.5,-40.5],[-1,0.5]],"c":false},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"tm","s":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":44,"s":[44],"e":[19]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":56,"s":[19],"e":[0]},{"t":89}],"ix":1},"e":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":44,"s":[45],"e":[20]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":56,"s":[20],"e":[1]},{"t":89}],"ix":2},"o":{"a":0,"k":0,"ix":3},"m":1,"ix":2,"nm":"Trim Paths 1","mn":"ADBE Vector Filter - Trim","hd":false},{"ty":"st","c":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":44,"s":[0.721568644047,0.847058832645,0.949019610882,1],"e":[0.701960802078,0.843137264252,0.670588254929,1]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":56,"s":[0.701960802078,0.843137264252,0.670588254929,1],"e":[0.549019634724,0.274509817362,0.709803938866,1]},{"t":66}],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":56,"s":[5],"e":[0]},{"t":89}],"ix":5},"lc":2,"lj":1,"ml":4,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Shape 1","np":3,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":44,"op":90,"st":-44,"bm":0},{"ddd":0,"ind":11,"ty":4,"nm":"Dot4","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":-69.3,"ix":10},"p":{"a":0,"k":[25,25,0],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[40,40,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0]],"o":[[0,0],[0,0]],"v":[[-37.5,-40.5],[-1,0.5]],"c":false},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"tm","s":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":44,"s":[47],"e":[29]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":56,"s":[29],"e":[9]},{"t":78}],"ix":1},"e":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":44,"s":[48],"e":[30]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":56,"s":[30],"e":[10]},{"t":78}],"ix":2},"o":{"a":0,"k":0,"ix":3},"m":1,"ix":2,"nm":"Trim Paths 1","mn":"ADBE Vector Filter - Trim","hd":false},{"ty":"st","c":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":44,"s":[0.800000011921,0.580392181873,0.929411768913,1],"e":[0.701960802078,0.847058832645,0.658823549747,1]},{"t":56}],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":44,"s":[5],"e":[2]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":56,"s":[2],"e":[0]},{"t":70}],"ix":5},"lc":2,"lj":1,"ml":4,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Shape 1","np":3,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":44,"op":90,"st":-44,"bm":0},{"ddd":0,"ind":12,"ty":4,"nm":"Dot3","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":-55.9,"ix":10},"p":{"a":0,"k":[25,25,0],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[40,40,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0]],"o":[[0,0],[0,0]],"v":[[-37.5,-40.5],[-1,0.5]],"c":false},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"tm","s":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":44,"s":[44],"e":[19]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":56,"s":[19],"e":[0]},{"t":89}],"ix":1},"e":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":44,"s":[45],"e":[20]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":56,"s":[20],"e":[1]},{"t":89}],"ix":2},"o":{"a":0,"k":0,"ix":3},"m":1,"ix":2,"nm":"Trim Paths 1","mn":"ADBE Vector Filter - Trim","hd":false},{"ty":"st","c":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":44,"s":[0.643137276173,0.811764717102,0.972549021244,1],"e":[0.701960802078,0.847058832645,0.658823549747,1]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":56,"s":[0.701960802078,0.847058832645,0.658823549747,1],"e":[0.549019634724,0.274509817362,0.709803938866,1]},{"t":66}],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":56,"s":[5],"e":[0]},{"t":89}],"ix":5},"lc":2,"lj":1,"ml":4,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Shape 1","np":3,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":44,"op":90,"st":-44,"bm":0},{"ddd":0,"ind":13,"ty":4,"nm":"Dot2","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":-13.4,"ix":10},"p":{"a":0,"k":[25,25,0],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[40,40,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0]],"o":[[0,0],[0,0]],"v":[[-37.5,-40.5],[-1,0.5]],"c":false},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"tm","s":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":44,"s":[47],"e":[29]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":56,"s":[29],"e":[9]},{"t":78}],"ix":1},"e":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":44,"s":[48],"e":[30]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":56,"s":[30],"e":[10]},{"t":78}],"ix":2},"o":{"a":0,"k":0,"ix":3},"m":1,"ix":2,"nm":"Trim Paths 1","mn":"ADBE Vector Filter - Trim","hd":false},{"ty":"st","c":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":44,"s":[0.607843160629,0.886274516582,0.78823530674,1],"e":[0.631372570992,0.509803950787,0.623529434204,1]},{"t":56}],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":44,"s":[5],"e":[2]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":56,"s":[2],"e":[0]},{"t":70}],"ix":5},"lc":2,"lj":1,"ml":4,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Shape 1","np":3,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":44,"op":90,"st":-44,"bm":0},{"ddd":0,"ind":14,"ty":4,"nm":"Dot1","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[25,25,0],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[40,40,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0]],"o":[[0,0],[0,0]],"v":[[-37.5,-40.5],[-1,0.5]],"c":false},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"tm","s":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":44,"s":[44],"e":[19]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":56,"s":[19],"e":[0]},{"t":89}],"ix":1},"e":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":44,"s":[45],"e":[20]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":56,"s":[20],"e":[1]},{"t":89}],"ix":2},"o":{"a":0,"k":0,"ix":3},"m":1,"ix":2,"nm":"Trim Paths 1","mn":"ADBE Vector Filter - Trim","hd":false},{"ty":"st","c":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":44,"s":[0.61960786581,0.882352948189,0.780392169952,1],"e":[0.800000011921,0.521568655968,0.760784327984,1]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":56,"s":[0.800000011921,0.521568655968,0.760784327984,1],"e":[0.549019634724,0.274509817362,0.709803938866,1]},{"t":66}],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":56,"s":[5],"e":[0]},{"t":89}],"ix":5},"lc":2,"lj":1,"ml":4,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Shape 1","np":3,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":44,"op":90,"st":-44,"bm":0},{"ddd":0,"ind":15,"ty":4,"nm":"C2","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[25,25,0],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[40,40,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"d":1,"ty":"el","s":{"a":1,"k":[{"i":{"x":[0.833,0.833],"y":[0.833,0.833]},"o":{"x":[0.167,0.167],"y":[0.167,0.167]},"n":["0p833_0p833_0p167_0p167","0p833_0p833_0p167_0p167"],"t":38,"s":[25.744,25.744],"e":[60.744,60.744]},{"t":45}],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"nm":"Ellipse Path 1","mn":"ADBE Vector Shape - Ellipse","hd":false},{"ty":"st","c":{"a":0,"k":[0.807843148708,0.57647061348,0.956862747669,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":38,"s":[23.3],"e":[1]},{"t":45}],"ix":5},"lc":1,"lj":1,"ml":4,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Ellipse 1","np":2,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":38,"op":46,"st":-47,"bm":0},{"ddd":0,"ind":16,"ty":4,"nm":"C1","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[25,25,0],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"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":33,"s":[4,4,100],"e":[40,40,100]},{"t":39}],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"d":1,"ty":"el","s":{"a":0,"k":[57.344,57.344],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"nm":"Ellipse Path 1","mn":"ADBE Vector Shape - Ellipse","hd":false},{"ty":"fl","c":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":33,"s":[1,0,0.257425785065,1],"e":[0.811764717102,0.564705908298,0.96862745285,1]},{"t":39}],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Ellipse 1","np":3,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":33,"op":39,"st":-46,"bm":0},{"ddd":0,"ind":17,"ty":4,"nm":"H2","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[25.217,25.85,0],"ix":2},"a":{"a":0,"k":[2.958,2.958,0],"ix":1},"s":{"a":1,"k":[{"i":{"x":[0.32,0.32,0.32],"y":[1,1,1]},"o":{"x":[0.68,0.68,0.68],"y":[0,0,0]},"n":["0p32_1_0p68_0","0p32_1_0p68_0","0p32_1_0p68_0"],"t":43,"s":[4,4,100],"e":[48.44,48.44,100]},{"i":{"x":[0.32,0.32,0.32],"y":[1,1,1]},"o":{"x":[0.68,0.68,0.68],"y":[0,0,0]},"n":["0p32_1_0p68_0","0p32_1_0p68_0","0p32_1_0p68_0"],"t":54,"s":[48.44,48.44,100],"e":[37.04,37.04,100]},{"i":{"x":[0.32,0.32,0.32],"y":[1,1,1]},"o":{"x":[0.68,0.68,0.68],"y":[0,0,0]},"n":["0p32_1_0p68_0","0p32_1_0p68_0","0p32_1_0p68_0"],"t":70,"s":[37.04,37.04,100],"e":[40,40,100]},{"t":91}],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[4.833,0],[0,-3.333],[-3.25,0],[0,8.333],[3.917,0],[0,0]],"o":[[-4.833,0],[0,7.667],[3.25,0],[0,-4.5],[-3.917,0],[0,0]],"v":[[-4.583,-10.167],[-11.25,-2.25],[2.833,16.083],[17.167,-2.333],[10.167,-10],[2.917,-5.917]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.835294127464,0.180392161012,0.321568638086,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Shape 1","np":3,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":43,"op":136,"st":-46,"bm":0},{"ddd":0,"ind":18,"ty":4,"nm":"H1","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[25.217,25.85,0],"ix":2},"a":{"a":0,"k":[2.958,2.958,0],"ix":1},"s":{"a":0,"k":[40,40,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[4.833,0],[0,-3.333],[-3.25,0],[0,8.333],[3.917,0],[0,0]],"o":[[-4.833,0],[0,7.667],[3.25,0],[0,-4.5],[-3.917,0],[0,0]],"v":[[-4.583,-10.167],[-11.25,-2.25],[2.833,16.083],[17.167,-2.333],[10.167,-10],[2.917,-5.917]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.674509823322,0.729411780834,0.764705896378,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Shape 1","np":3,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":33,"st":-46,"bm":0}]}
\ No newline at end of file
diff --git a/LottieSample/src/main/res/values/colors.xml b/LottieSample/src/main/res/values/colors.xml
index 96ad189..9a3e593 100644
--- a/LottieSample/src/main/res/values/colors.xml
+++ b/LottieSample/src/main/res/values/colors.xml
@@ -9,6 +9,7 @@
<color name="text_color_dark">#484848</color>
<color name="text_color_placeholder">#BABABA</color>
<color name="tab_bar_underline">#00D1C1</color>
+ <color name="loading_placeholder">#c4c4c4</color>
<color name="background_color1">#ffffff</color>
<color name="background_color1_stroke">#848484</color>
diff --git a/LottieSample/src/main/res/values/strings.xml b/LottieSample/src/main/res/values/strings.xml
index 8b6c7a3..b213819 100644
--- a/LottieSample/src/main/res/values/strings.xml
+++ b/LottieSample/src/main/res/values/strings.xml
@@ -82,5 +82,6 @@
<string name="showcase_item_dynamic_properties">Dynamic\nProperties</string>
<string name="showcase_item_animated_text">Animated\nText</string>
<string name="showcase_item_dynamic_text">Dynamic\nText</string>
+ <string name="showcase_item_recycler_viwe">RecyclerView</string>
<string name="bullseye_drag_dot">Drag the blue dot</string>
</resources>
diff --git a/lottie/src/main/java/com/airbnb/lottie/LottieComposition.java b/lottie/src/main/java/com/airbnb/lottie/LottieComposition.java
index e61ffe9..5a0a9ce 100644
--- a/lottie/src/main/java/com/airbnb/lottie/LottieComposition.java
+++ b/lottie/src/main/java/com/airbnb/lottie/LottieComposition.java
@@ -153,6 +153,10 @@
}
/**
+ * This will be removed in the next version of Lottie. {@link LottieCompositionFactory} has improved
+ * API names, failure handlers, and will return in-progress tasks so you will never parse the same
+ * animation twice in parallel.
+ *
* @see LottieCompositionFactory
*/
@Deprecated
@@ -163,6 +167,7 @@
/**
* @see LottieCompositionFactory#fromAsset(Context, String)
*/
+ @Deprecated
public static Cancellable fromAssetFileName(Context context, String fileName, OnCompositionLoadedListener l) {
ListenerAdapter listener = new ListenerAdapter(l);
LottieCompositionFactory.fromAsset(context, fileName).addListener(listener);
@@ -172,6 +177,7 @@
/**
* @see LottieCompositionFactory#fromRawRes(Context, int)
*/
+ @Deprecated
public static Cancellable fromRawFile(Context context, @RawRes int resId, OnCompositionLoadedListener l) {
ListenerAdapter listener = new ListenerAdapter(l);
LottieCompositionFactory.fromRawRes(context, resId).addListener(listener);
@@ -181,6 +187,7 @@
/**
* @see LottieCompositionFactory#fromJsonInputStream(InputStream)
*/
+ @Deprecated
public static Cancellable fromInputStream(InputStream stream, OnCompositionLoadedListener l) {
ListenerAdapter listener = new ListenerAdapter(l);
LottieCompositionFactory.fromJsonInputStream(stream, null).addListener(listener);
@@ -190,6 +197,7 @@
/**
* @see LottieCompositionFactory#fromJsonString(String)
*/
+ @Deprecated
public static Cancellable fromJsonString(String jsonString, OnCompositionLoadedListener l) {
ListenerAdapter listener = new ListenerAdapter(l);
LottieCompositionFactory.fromJsonString(jsonString, null).addListener(listener);
@@ -199,6 +207,7 @@
/**
* @see LottieCompositionFactory#fromJsonReader(JsonReader)
*/
+ @Deprecated
public static Cancellable fromJsonReader(JsonReader reader, OnCompositionLoadedListener l) {
ListenerAdapter listener = new ListenerAdapter(l);
LottieCompositionFactory.fromJsonReader(reader, null).addListener(listener);
@@ -210,6 +219,7 @@
*/
@Nullable
@WorkerThread
+ @Deprecated
public static LottieComposition fromFileSync(Context context, String fileName) {
return LottieCompositionFactory.fromAssetSync(context, fileName).getValue();
}
@@ -219,6 +229,7 @@
*/
@Nullable
@WorkerThread
+ @Deprecated
public static LottieComposition fromInputStreamSync(InputStream stream) {
return LottieCompositionFactory.fromJsonInputStreamSync(stream, null).getValue();
}
@@ -230,6 +241,7 @@
*/
@Nullable
@WorkerThread
+ @Deprecated
public static LottieComposition fromInputStreamSync(InputStream stream, boolean close) {
if (close) {
Log.w(L.TAG, "Lottie now auto-closes input stream!");
@@ -242,6 +254,7 @@
*/
@Nullable
@WorkerThread
+ @Deprecated
public static LottieComposition fromJsonSync(@SuppressWarnings("unused") Resources res, JSONObject json) {
return LottieCompositionFactory.fromJsonSync(json, null).getValue();
}
@@ -251,6 +264,7 @@
*/
@Nullable
@WorkerThread
+ @Deprecated
public static LottieComposition fromJsonSync(String json) {
return LottieCompositionFactory.fromJsonStringSync(json, null).getValue();
}
@@ -260,6 +274,7 @@
*/
@Nullable
@WorkerThread
+ @Deprecated
public static LottieComposition fromJsonSync(JsonReader reader) throws IOException {
return LottieCompositionFactory.fromJsonReaderSync(reader, null).getValue();
}
diff --git a/lottie/src/main/java/com/airbnb/lottie/LottieCompositionFactory.java b/lottie/src/main/java/com/airbnb/lottie/LottieCompositionFactory.java
index 581f690..ce71a44 100644
--- a/lottie/src/main/java/com/airbnb/lottie/LottieCompositionFactory.java
+++ b/lottie/src/main/java/com/airbnb/lottie/LottieCompositionFactory.java
@@ -29,8 +29,18 @@
/**
* Helpers to create or cache a LottieComposition.
+ *
+ * All factory methods take a cache key. The animation will be stored in an LRU cache for future use.
+ * In-progress tasks will also be held so they can be returned for subsequent requests for the same
+ * animation prior to the cache being populated.
*/
public class LottieCompositionFactory {
+ /**
+ * Keep a map of cache keys to in-progress tasks and return them for new requests.
+ * Without this, simultaneous requests to parse a composition will trigger multiple parallel
+ * parse tasks prior to the cache getting populated.
+ */
+ private static final Map<String, LottieTask<LottieComposition>> taskCache = new HashMap<>();
private LottieCompositionFactory() {
}
@@ -64,7 +74,7 @@
public static LottieTask<LottieComposition> fromAsset(Context context, final String fileName) {
// Prevent accidentally leaking an Activity.
final Context appContext = context.getApplicationContext();
- return new LottieTask<>(new Callable<LottieResult<LottieComposition>>() {
+ return cache(fileName, new Callable<LottieResult<LottieComposition>>() {
@Override public LottieResult<LottieComposition> call() {
return fromAssetSync(appContext, fileName);
}
@@ -99,7 +109,7 @@
public static LottieTask<LottieComposition> fromRawRes(Context context, @RawRes final int rawRes) {
// Prevent accidentally leaking an Activity.
final Context appContext = context.getApplicationContext();
- return new LottieTask<>(new Callable<LottieResult<LottieComposition>>() {
+ return cache(rawResCacheKey(rawRes), new Callable<LottieResult<LottieComposition>>() {
@Override public LottieResult<LottieComposition> call() throws Exception {
return fromRawResSync(appContext, rawRes);
}
@@ -112,21 +122,25 @@
* The resource id will be used as a cache key so future usages won't parse the json again.
*/
@WorkerThread
- public static LottieResult<LottieComposition> fromRawResSync(Context context, @RawRes int resId) {
+ public static LottieResult<LottieComposition> fromRawResSync(Context context, @RawRes int rawRes) {
try {
- return fromJsonInputStreamSync(context.getResources().openRawResource(resId), "rawRes_" + resId);
+ return fromJsonInputStreamSync(context.getResources().openRawResource(rawRes), rawResCacheKey(rawRes));
} catch (Resources.NotFoundException e) {
return new LottieResult<>(e);
}
}
+ private static String rawResCacheKey(@RawRes int resId) {
+ return "rawRes_" + resId;
+ }
+
/**
* Auto-closes the stream.
*
* @see #fromJsonInputStreamSync(InputStream, boolean)
*/
public static LottieTask<LottieComposition> fromJsonInputStream(final InputStream stream, @Nullable final String cacheKey) {
- return new LottieTask<>(new Callable<LottieResult<LottieComposition>>() {
+ return cache(cacheKey, new Callable<LottieResult<LottieComposition>>() {
@Override public LottieResult<LottieComposition> call() throws Exception {
return fromJsonInputStreamSync(stream, cacheKey);
}
@@ -157,7 +171,7 @@
*/
@Deprecated
public static LottieTask<LottieComposition> fromJson(final JSONObject json, @Nullable final String cacheKey) {
- return new LottieTask<>(new Callable<LottieResult<LottieComposition>>() {
+ return cache(cacheKey, new Callable<LottieResult<LottieComposition>>() {
@Override public LottieResult<LottieComposition> call() throws Exception {
return fromJsonSync(json, cacheKey);
}
@@ -179,7 +193,7 @@
* @see #fromJsonStringSync(String)
*/
public static LottieTask<LottieComposition> fromJsonString(final String json, @Nullable final String cacheKey) {
- return new LottieTask<>(new Callable<LottieResult<LottieComposition>>() {
+ return cache(cacheKey, new Callable<LottieResult<LottieComposition>>() {
@Override public LottieResult<LottieComposition> call() throws Exception {
return fromJsonStringSync(json, cacheKey);
}
@@ -196,7 +210,7 @@
}
public static LottieTask<LottieComposition> fromJsonReader(final JsonReader reader, @Nullable final String cacheKey) {
- return new LottieTask<>(new Callable<LottieResult<LottieComposition>>() {
+ return cache(cacheKey, new Callable<LottieResult<LottieComposition>>() {
@Override public LottieResult<LottieComposition> call() throws Exception {
return fromJsonReaderSync(reader, cacheKey);
}
@@ -218,7 +232,7 @@
}
public static LottieTask<LottieComposition> fromZipStream(final ZipInputStream inputStream, @Nullable final String cacheKey) {
- return new LottieTask<>(new Callable<LottieResult<LottieComposition>>() {
+ return cache(cacheKey, new Callable<LottieResult<LottieComposition>>() {
@Override public LottieResult<LottieComposition> call() throws Exception {
return fromZipStreamSync(inputStream, cacheKey);
}
@@ -297,4 +311,29 @@
}
return null;
}
+
+ /**
+ * First, check to see if there are any in-progress tasks associated with the cache key and return it if there is.
+ * If not, create a new task for the callable.
+ * Then, add the new task to the task cache and set up listeners to it gets cleared when done.
+ */
+ private static LottieTask<LottieComposition> cache(final String cacheKey, Callable<LottieResult<LottieComposition>> callable) {
+ if (taskCache.containsKey(cacheKey)) {
+ return taskCache.get(cacheKey);
+ }
+
+ LottieTask<LottieComposition> task = new LottieTask<>(callable);
+ task.addListener(new LottieListener<LottieComposition>() {
+ @Override public void onResult(LottieComposition result) {
+ taskCache.remove(cacheKey);
+ }
+ });
+ task.addFailureListener(new LottieListener<Throwable>() {
+ @Override public void onResult(Throwable result) {
+ taskCache.remove(cacheKey);
+ }
+ });
+ taskCache.put(cacheKey, task);
+ return task;
+ }
}
diff --git a/lottie/src/main/java/com/airbnb/lottie/LottieTask.java b/lottie/src/main/java/com/airbnb/lottie/LottieTask.java
index 6421b82..d4e28b1 100644
--- a/lottie/src/main/java/com/airbnb/lottie/LottieTask.java
+++ b/lottie/src/main/java/com/airbnb/lottie/LottieTask.java
@@ -3,6 +3,7 @@
import android.os.Handler;
import android.os.Looper;
import android.support.annotation.Nullable;
+import android.support.annotation.RestrictTo;
import android.support.annotation.VisibleForTesting;
import android.util.Log;
@@ -42,6 +43,7 @@
@Nullable private LottieResult<T> result = null;
+ @RestrictTo(RestrictTo.Scope.LIBRARY)
public LottieTask(Callable<LottieResult<T>> runnable) {
this(runnable, false);
}
@@ -49,6 +51,7 @@
/**
* runNow is only used for testing.
*/
+ @RestrictTo(RestrictTo.Scope.LIBRARY)
LottieTask(Callable<LottieResult<T>> runnable, boolean runNow) {
task = new FutureTask<>(runnable);