@amazon-devices/lottie-react-native 2.0.1758683737
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +7 -0
- package/SystemBundles/90296ccfe5ff2db2f9fe68a18eca092f8b7c17d1125cfafc612d18788fe9bce6.bundle +10322 -0
- package/SystemBundles/90296ccfe5ff2db2f9fe68a18eca092f8b7c17d1125cfafc612d18788fe9bce6.map +1 -0
- package/SystemModules/amzn__lottie-react-native-2.modules.txt +13 -0
- package/SystemModules/amzn__lottie-react-native-2.private.modules.txt +92 -0
- package/SystemModules/keplerscript-system-bundle-config.json +7 -0
- package/THIRD_PARTY_NOTICES.txt +640 -0
- package/android/build.gradle +120 -0
- package/android/gradle.properties +27 -0
- package/android/src/main/AndroidManifest.xml +6 -0
- package/android/src/main/java/com/airbnb/android/react/lottie/LottieAnimationViewManagerImpl.kt +260 -0
- package/android/src/main/java/com/airbnb/android/react/lottie/LottieAnimationViewPropertyManager.kt +156 -0
- package/android/src/main/java/com/airbnb/android/react/lottie/LottiePackage.kt +18 -0
- package/android/src/newarch/com/airbnb/android/react/lottie/LottieAnimationViewManager.kt +219 -0
- package/android/src/oldarch/com/airbnb/android/react/lottie/LottieAnimationViewManager.kt +187 -0
- package/ios/Fabric/LottieAnimationViewComponentView.h +28 -0
- package/ios/Fabric/LottieAnimationViewComponentView.mm +140 -0
- package/ios/Fabric/LottieContainerView.h +33 -0
- package/ios/Fabric/RNLottieFabricConversions.h +29 -0
- package/ios/LottieReactNative/AnimationViewManagerModule.swift +88 -0
- package/ios/LottieReactNative/Bridging.h +4 -0
- package/ios/LottieReactNative/ContainerView.swift +281 -0
- package/ios/LottieReactNative/LRNAnimationViewManagerObjC.m +25 -0
- package/ios/LottieReactNative/PlatformColor.swift +31 -0
- package/ios/LottieReactNative/RCTConvert+Lottie.h +7 -0
- package/ios/LottieReactNative/RCTConvert+Lottie.m +24 -0
- package/ios/LottieReactNative.xcodeproj/project.pbxproj +449 -0
- package/ios/LottieReactNative.xcodeproj/project.xcworkspace/contents.xcworkspacedata +7 -0
- package/ios/LottieReactNative.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist +8 -0
- package/kepler-compatibility.json +8 -0
- package/kepler-transformed-package-info.json +3 -0
- package/lib/commonjs/LottieView.js +207 -0
- package/lib/commonjs/LottieView.js.map +1 -0
- package/lib/commonjs/LottieView.types.js +6 -0
- package/lib/commonjs/LottieView.types.js.map +1 -0
- package/lib/commonjs/index.js +9 -0
- package/lib/commonjs/index.js.map +1 -0
- package/lib/commonjs/specs/LottieAnimationViewNativeComponent.js +97 -0
- package/lib/commonjs/specs/LottieAnimationViewNativeComponent.js.map +1 -0
- package/lib/module/LottieView.js +201 -0
- package/lib/module/LottieView.js.map +1 -0
- package/lib/module/LottieView.types.js +2 -0
- package/lib/module/LottieView.types.js.map +1 -0
- package/lib/module/index.js +3 -0
- package/lib/module/index.js.map +1 -0
- package/lib/module/specs/LottieAnimationViewNativeComponent.js +91 -0
- package/lib/module/specs/LottieAnimationViewNativeComponent.js.map +1 -0
- package/lib/typescript/LottieView.d.ts +27 -0
- package/lib/typescript/LottieView.types.d.ts +206 -0
- package/lib/typescript/index.d.ts +2 -0
- package/lib/typescript/specs/LottieAnimationViewNativeComponent.d.ts +61 -0
- package/lottie-react-native.podspec +44 -0
- package/package.json +1 -0
- package/react-native.config.js +32 -0
- package/src/LottieView.tsx +257 -0
- package/src/LottieView.types.ts +275 -0
- package/src/__tests__/__snapshots__/validate-public-api.test.js.snap +248 -0
- package/src/__tests__/validate-public-api.test.js +33 -0
- package/src/index.tsx +2 -0
- package/src/specs/LottieAnimationViewNativeComponent.ts +170 -0
|
@@ -0,0 +1,120 @@
|
|
|
1
|
+
buildscript {
|
|
2
|
+
def kotlin_version = rootProject.ext.has('kotlinVersion') ? rootProject.ext.get('kotlinVersion') : project.properties['lottiereactnative_kotlinVersion']
|
|
3
|
+
|
|
4
|
+
repositories {
|
|
5
|
+
google()
|
|
6
|
+
gradlePluginPortal()
|
|
7
|
+
mavenCentral()
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
dependencies {
|
|
11
|
+
classpath("com.android.tools.build:gradle:7.2.2")
|
|
12
|
+
classpath("org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version")
|
|
13
|
+
}
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
def getExtOrDefault(name, defaultValue) {
|
|
17
|
+
rootProject.ext.has(name) ? rootProject.ext.get(name) : defaultValue
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
def isNewArchitectureEnabled() {
|
|
21
|
+
// To opt-in for the New Architecture, you can either:
|
|
22
|
+
// - Set `newArchEnabled` to true inside the `gradle.properties` file
|
|
23
|
+
// - Invoke gradle with `-newArchEnabled=true`
|
|
24
|
+
// - Set an environment variable `ORG_GRADLE_PROJECT_newArchEnabled=true`
|
|
25
|
+
return project.hasProperty("newArchEnabled") && project.newArchEnabled == "true"
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
apply plugin: 'com.android.library'
|
|
29
|
+
apply plugin: 'kotlin-android'
|
|
30
|
+
|
|
31
|
+
if (isNewArchitectureEnabled()) {
|
|
32
|
+
apply plugin: 'com.facebook.react'
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
android {
|
|
36
|
+
compileSdk getExtOrDefault('compileSdkVersion', 31)
|
|
37
|
+
|
|
38
|
+
// Used to override the NDK path/version on internal CI or by allowing
|
|
39
|
+
// users to customize the NDK path/version from their root project (e.g. for M1 support)
|
|
40
|
+
if (rootProject.hasProperty("ndkPath")) {
|
|
41
|
+
ndkPath rootProject.ext.ndkPath
|
|
42
|
+
}
|
|
43
|
+
if (rootProject.hasProperty("ndkVersion")) {
|
|
44
|
+
ndkVersion rootProject.ext.ndkVersion
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
defaultConfig {
|
|
48
|
+
minSdkVersion getExtOrDefault('minSdkVersion', 21)
|
|
49
|
+
targetSdkVersion getExtOrDefault('targetSdkVersion', 31)
|
|
50
|
+
buildConfigField "boolean", "IS_NEW_ARCHITECTURE_ENABLED", isNewArchitectureEnabled().toString()
|
|
51
|
+
|
|
52
|
+
ndk {
|
|
53
|
+
abiFilters(*reactNativeArchitectures())
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
packagingOptions {
|
|
58
|
+
exclude "**/libreact_render*.so"
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
packagingOptions {
|
|
62
|
+
excludes = [
|
|
63
|
+
"META-INF",
|
|
64
|
+
"META-INF/**",
|
|
65
|
+
"**/libc++_shared.so",
|
|
66
|
+
"**/libfabricjni.so",
|
|
67
|
+
"**/libfbjni.so",
|
|
68
|
+
"**/libjsi.so",
|
|
69
|
+
"**/libfolly_json.so",
|
|
70
|
+
"**/libfolly_runtime.so",
|
|
71
|
+
"**/libglog.so",
|
|
72
|
+
"**/libreact_codegen_rncore.so",
|
|
73
|
+
"**/libreact_debug.so",
|
|
74
|
+
"**/libreact_nativemodule_core.so",
|
|
75
|
+
"**/libreact_render_componentregistry.so",
|
|
76
|
+
"**/libreact_render_core.so",
|
|
77
|
+
"**/libreact_render_debug.so",
|
|
78
|
+
"**/libreact_render_graphics.so",
|
|
79
|
+
"**/librrc_view.so",
|
|
80
|
+
"**/libruntimeexecutor.so",
|
|
81
|
+
"**/libturbomodulejsijni.so",
|
|
82
|
+
"**/libyoga.so",
|
|
83
|
+
]
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
sourceSets {
|
|
87
|
+
main {
|
|
88
|
+
if (isNewArchitectureEnabled()) {
|
|
89
|
+
java.srcDirs += ['src/newarch', "${project.buildDir}/generated/source/codegen/java"]
|
|
90
|
+
} else {
|
|
91
|
+
java.srcDirs += ['src/oldarch']
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
def reactNativeArchitectures() {
|
|
98
|
+
def value = project.getProperties().get("reactNativeArchitectures")
|
|
99
|
+
return value ? value.split(",") : ["armeabi-v7a", "x86", "x86_64", "arm64-v8a"]
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
repositories {
|
|
103
|
+
google()
|
|
104
|
+
maven {
|
|
105
|
+
// All of React Native (JS, Obj-C sources, Android binaries) is installed from npm
|
|
106
|
+
url "$projectDir/../node_modules/react-native/android"
|
|
107
|
+
}
|
|
108
|
+
mavenCentral()
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
def kotlin_version = getExtOrDefault('kotlinVersion', project.properties['lottiereactnative_kotlinVersion'])
|
|
112
|
+
|
|
113
|
+
dependencies {
|
|
114
|
+
implementation "org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version"
|
|
115
|
+
|
|
116
|
+
//noinspection GradleDynamicVersion
|
|
117
|
+
implementation 'com.facebook.react:react-native:+' // From node_modules
|
|
118
|
+
|
|
119
|
+
implementation "com.airbnb.android:lottie:5.2.0"
|
|
120
|
+
}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
# Project-wide Gradle settings.
|
|
2
|
+
|
|
3
|
+
# IDE (e.g. Android Studio) users:
|
|
4
|
+
# Gradle settings configured through the IDE *will override*
|
|
5
|
+
# any settings specified in this file.
|
|
6
|
+
|
|
7
|
+
# For more details on how to configure your build environment visit
|
|
8
|
+
# http://www.gradle.org/docs/current/userguide/build_environment.html
|
|
9
|
+
|
|
10
|
+
# Specifies the JVM arguments used for the daemon process.
|
|
11
|
+
# The setting is particularly useful for tweaking memory settings.
|
|
12
|
+
# Default value: -Xmx512m -XX:MaxMetaspaceSize=256m
|
|
13
|
+
org.gradle.jvmargs=-Xmx2048m -XX:MaxMetaspaceSize=512m
|
|
14
|
+
|
|
15
|
+
# When configured, Gradle will run in incubating parallel mode.
|
|
16
|
+
# This option should only be used with decoupled projects. More details, visit
|
|
17
|
+
# http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects
|
|
18
|
+
# org.gradle.parallel=true
|
|
19
|
+
|
|
20
|
+
# AndroidX package structure to make it clearer which packages are bundled with the
|
|
21
|
+
# Android operating system, and which are packaged with your app's APK
|
|
22
|
+
# https://developer.android.com/topic/libraries/support-library/androidx-rn
|
|
23
|
+
android.useAndroidX=true
|
|
24
|
+
# Automatically convert third-party libraries to use AndroidX
|
|
25
|
+
android.enableJetifier=true
|
|
26
|
+
|
|
27
|
+
lottiereactnative_kotlinVersion=1.7.10
|
package/android/src/main/java/com/airbnb/android/react/lottie/LottieAnimationViewManagerImpl.kt
ADDED
|
@@ -0,0 +1,260 @@
|
|
|
1
|
+
package com.airbnb.android.react.lottie
|
|
2
|
+
|
|
3
|
+
import android.os.Handler
|
|
4
|
+
import android.os.Looper
|
|
5
|
+
import android.view.View
|
|
6
|
+
import android.view.View.OnAttachStateChangeListener
|
|
7
|
+
import android.widget.ImageView
|
|
8
|
+
import androidx.core.view.ViewCompat
|
|
9
|
+
import com.airbnb.lottie.LottieAnimationView
|
|
10
|
+
import com.airbnb.lottie.RenderMode
|
|
11
|
+
import com.facebook.react.bridge.ReadableArray
|
|
12
|
+
import com.facebook.react.common.MapBuilder
|
|
13
|
+
import com.facebook.react.uimanager.ThemedReactContext
|
|
14
|
+
import java.io.BufferedReader
|
|
15
|
+
import java.io.InputStreamReader
|
|
16
|
+
import java.net.URL
|
|
17
|
+
import kotlin.concurrent.thread
|
|
18
|
+
|
|
19
|
+
internal object LottieAnimationViewManagerImpl {
|
|
20
|
+
const val REACT_CLASS = "LottieAnimationView"
|
|
21
|
+
|
|
22
|
+
@JvmStatic
|
|
23
|
+
val exportedViewConstants: Map<String, Any>
|
|
24
|
+
get() = MapBuilder.builder<String, Any>()
|
|
25
|
+
.put("VERSION", 1)
|
|
26
|
+
.build()
|
|
27
|
+
|
|
28
|
+
@JvmStatic
|
|
29
|
+
fun createViewInstance(context: ThemedReactContext): LottieAnimationView {
|
|
30
|
+
return LottieAnimationView(context).apply {
|
|
31
|
+
scaleType = ImageView.ScaleType.CENTER_INSIDE
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
@JvmStatic
|
|
36
|
+
fun getExportedCustomBubblingEventTypeConstants(): MutableMap<String, Any> {
|
|
37
|
+
return MapBuilder.of(
|
|
38
|
+
"animationFinish",
|
|
39
|
+
MapBuilder.of("phasedRegistrationNames", MapBuilder.of("bubbled", "onAnimationFinish"))
|
|
40
|
+
)
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
@JvmStatic
|
|
44
|
+
fun play(view: LottieAnimationView, startFrame: Int, endFrame: Int) {
|
|
45
|
+
Handler(Looper.getMainLooper()).post {
|
|
46
|
+
if (startFrame != -1 && endFrame != -1) {
|
|
47
|
+
if (startFrame > endFrame) {
|
|
48
|
+
view.setMinAndMaxFrame(endFrame, startFrame)
|
|
49
|
+
if (view.speed > 0) {
|
|
50
|
+
view.reverseAnimationSpeed()
|
|
51
|
+
}
|
|
52
|
+
} else {
|
|
53
|
+
view.setMinAndMaxFrame(startFrame, endFrame)
|
|
54
|
+
if (view.speed < 0) {
|
|
55
|
+
view.reverseAnimationSpeed()
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
if (ViewCompat.isAttachedToWindow(view)) {
|
|
60
|
+
view.progress = 0f
|
|
61
|
+
view.playAnimation()
|
|
62
|
+
} else {
|
|
63
|
+
view.addOnAttachStateChangeListener(object : OnAttachStateChangeListener {
|
|
64
|
+
override fun onViewAttachedToWindow(v: View) {
|
|
65
|
+
val listenerView = v as LottieAnimationView
|
|
66
|
+
listenerView.progress = 0f
|
|
67
|
+
listenerView.playAnimation()
|
|
68
|
+
listenerView.removeOnAttachStateChangeListener(this)
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
override fun onViewDetachedFromWindow(v: View) {
|
|
72
|
+
val listenerView = v as LottieAnimationView
|
|
73
|
+
listenerView.removeOnAttachStateChangeListener(this)
|
|
74
|
+
}
|
|
75
|
+
})
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
@JvmStatic
|
|
81
|
+
fun reset(view: LottieAnimationView) {
|
|
82
|
+
Handler(Looper.getMainLooper()).post {
|
|
83
|
+
if (ViewCompat.isAttachedToWindow(view)) {
|
|
84
|
+
view.cancelAnimation()
|
|
85
|
+
view.progress = 0f
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
@JvmStatic
|
|
91
|
+
fun pause(view: LottieAnimationView) {
|
|
92
|
+
Handler(Looper.getMainLooper()).post {
|
|
93
|
+
if (ViewCompat.isAttachedToWindow(view)) {
|
|
94
|
+
view.pauseAnimation()
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
@JvmStatic
|
|
100
|
+
fun resume(view: LottieAnimationView) {
|
|
101
|
+
Handler(Looper.getMainLooper()).post {
|
|
102
|
+
if (ViewCompat.isAttachedToWindow(view)) {
|
|
103
|
+
view.resumeAnimation()
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
@JvmStatic
|
|
109
|
+
fun setSourceName(
|
|
110
|
+
name: String?,
|
|
111
|
+
viewManager: LottieAnimationViewPropertyManager
|
|
112
|
+
) {
|
|
113
|
+
// To match the behaviour on iOS we expect the source name to be
|
|
114
|
+
// extensionless. This means "myAnimation" corresponds to a file
|
|
115
|
+
// named `myAnimation.json` in `main/assets`. To maintain backwards
|
|
116
|
+
// compatibility we only add the .json extension if no extension is
|
|
117
|
+
// passed.
|
|
118
|
+
var resultSourceName = name
|
|
119
|
+
if (resultSourceName?.contains(".") == false) {
|
|
120
|
+
resultSourceName = "$resultSourceName.json"
|
|
121
|
+
}
|
|
122
|
+
viewManager.animationName = resultSourceName
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
@JvmStatic
|
|
126
|
+
fun setSourceJson(
|
|
127
|
+
json: String?,
|
|
128
|
+
propManagersMap: LottieAnimationViewPropertyManager
|
|
129
|
+
) {
|
|
130
|
+
propManagersMap.animationJson = json
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
@JvmStatic
|
|
134
|
+
fun setSourceURL(
|
|
135
|
+
urlString: String?,
|
|
136
|
+
propManagersMap: LottieAnimationViewPropertyManager
|
|
137
|
+
) {
|
|
138
|
+
thread {
|
|
139
|
+
BufferedReader(InputStreamReader(URL(urlString).openStream())).useLines {
|
|
140
|
+
Handler(Looper.getMainLooper()).post {
|
|
141
|
+
propManagersMap.animationJson = it.toString()
|
|
142
|
+
propManagersMap.commitChanges()
|
|
143
|
+
}
|
|
144
|
+
}
|
|
145
|
+
}
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
@JvmStatic
|
|
149
|
+
fun setCacheComposition(view: LottieAnimationView, cacheComposition: Boolean) {
|
|
150
|
+
view.setCacheComposition(cacheComposition)
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
@JvmStatic
|
|
154
|
+
fun setResizeMode(
|
|
155
|
+
resizeMode: String?,
|
|
156
|
+
viewManager: LottieAnimationViewPropertyManager
|
|
157
|
+
) {
|
|
158
|
+
var mode: ImageView.ScaleType? = null
|
|
159
|
+
when (resizeMode) {
|
|
160
|
+
"cover" -> {
|
|
161
|
+
mode = ImageView.ScaleType.CENTER_CROP
|
|
162
|
+
}
|
|
163
|
+
"contain" -> {
|
|
164
|
+
mode = ImageView.ScaleType.CENTER_INSIDE
|
|
165
|
+
}
|
|
166
|
+
"center" -> {
|
|
167
|
+
mode = ImageView.ScaleType.CENTER
|
|
168
|
+
}
|
|
169
|
+
}
|
|
170
|
+
viewManager.scaleType = mode
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
@JvmStatic
|
|
174
|
+
fun setRenderMode(
|
|
175
|
+
renderMode: String?,
|
|
176
|
+
viewManager: LottieAnimationViewPropertyManager
|
|
177
|
+
) {
|
|
178
|
+
var mode: RenderMode? = null
|
|
179
|
+
when (renderMode) {
|
|
180
|
+
"AUTOMATIC" -> {
|
|
181
|
+
mode = RenderMode.AUTOMATIC
|
|
182
|
+
}
|
|
183
|
+
"HARDWARE" -> {
|
|
184
|
+
mode = RenderMode.HARDWARE
|
|
185
|
+
}
|
|
186
|
+
"SOFTWARE" -> {
|
|
187
|
+
mode = RenderMode.SOFTWARE
|
|
188
|
+
}
|
|
189
|
+
}
|
|
190
|
+
viewManager.renderMode = mode
|
|
191
|
+
}
|
|
192
|
+
|
|
193
|
+
@JvmStatic
|
|
194
|
+
fun setHardwareAcceleration(
|
|
195
|
+
hardwareAccelerationAndroid: Boolean,
|
|
196
|
+
viewManager: LottieAnimationViewPropertyManager
|
|
197
|
+
) {
|
|
198
|
+
var layerType: Int? = View.LAYER_TYPE_SOFTWARE
|
|
199
|
+
if (hardwareAccelerationAndroid) {
|
|
200
|
+
layerType = View.LAYER_TYPE_HARDWARE
|
|
201
|
+
}
|
|
202
|
+
viewManager.layerType = layerType
|
|
203
|
+
}
|
|
204
|
+
|
|
205
|
+
@JvmStatic
|
|
206
|
+
fun setProgress(
|
|
207
|
+
progress: Float,
|
|
208
|
+
viewManager: LottieAnimationViewPropertyManager
|
|
209
|
+
) {
|
|
210
|
+
viewManager.progress = progress
|
|
211
|
+
}
|
|
212
|
+
|
|
213
|
+
@JvmStatic
|
|
214
|
+
fun setSpeed(
|
|
215
|
+
speed: Double,
|
|
216
|
+
viewManager: LottieAnimationViewPropertyManager
|
|
217
|
+
) {
|
|
218
|
+
viewManager.speed = speed.toFloat()
|
|
219
|
+
}
|
|
220
|
+
|
|
221
|
+
@JvmStatic
|
|
222
|
+
fun setLoop(
|
|
223
|
+
loop: Boolean,
|
|
224
|
+
viewManager: LottieAnimationViewPropertyManager
|
|
225
|
+
) {
|
|
226
|
+
viewManager.loop = loop
|
|
227
|
+
}
|
|
228
|
+
|
|
229
|
+
@JvmStatic
|
|
230
|
+
fun setEnableMergePaths(
|
|
231
|
+
enableMergePaths: Boolean,
|
|
232
|
+
viewManager: LottieAnimationViewPropertyManager
|
|
233
|
+
) {
|
|
234
|
+
viewManager.enableMergePaths = enableMergePaths
|
|
235
|
+
}
|
|
236
|
+
|
|
237
|
+
@JvmStatic
|
|
238
|
+
fun setImageAssetsFolder(
|
|
239
|
+
imageAssetsFolder: String?,
|
|
240
|
+
viewManager: LottieAnimationViewPropertyManager
|
|
241
|
+
) {
|
|
242
|
+
viewManager.imageAssetsFolder = imageAssetsFolder
|
|
243
|
+
}
|
|
244
|
+
|
|
245
|
+
@JvmStatic
|
|
246
|
+
fun setColorFilters(
|
|
247
|
+
colorFilters: ReadableArray?,
|
|
248
|
+
viewManager: LottieAnimationViewPropertyManager
|
|
249
|
+
) {
|
|
250
|
+
viewManager.colorFilters = colorFilters
|
|
251
|
+
}
|
|
252
|
+
|
|
253
|
+
@JvmStatic
|
|
254
|
+
fun setTextFilters(
|
|
255
|
+
textFilters: ReadableArray?,
|
|
256
|
+
viewManager: LottieAnimationViewPropertyManager
|
|
257
|
+
) {
|
|
258
|
+
viewManager.textFilters = textFilters
|
|
259
|
+
}
|
|
260
|
+
}
|
package/android/src/main/java/com/airbnb/android/react/lottie/LottieAnimationViewPropertyManager.kt
ADDED
|
@@ -0,0 +1,156 @@
|
|
|
1
|
+
package com.airbnb.android.react.lottie
|
|
2
|
+
|
|
3
|
+
import com.airbnb.lottie.LottieAnimationView
|
|
4
|
+
import java.lang.ref.WeakReference
|
|
5
|
+
import android.widget.ImageView
|
|
6
|
+
import com.facebook.react.bridge.ReadableArray
|
|
7
|
+
import com.airbnb.lottie.RenderMode
|
|
8
|
+
import com.airbnb.lottie.TextDelegate
|
|
9
|
+
import com.airbnb.lottie.LottieDrawable
|
|
10
|
+
import com.facebook.react.bridge.ReadableType
|
|
11
|
+
import com.facebook.react.bridge.ColorPropConverter
|
|
12
|
+
import android.graphics.ColorFilter
|
|
13
|
+
import com.airbnb.lottie.SimpleColorFilter
|
|
14
|
+
import com.airbnb.lottie.model.KeyPath
|
|
15
|
+
import com.airbnb.lottie.value.LottieValueCallback
|
|
16
|
+
import com.airbnb.lottie.LottieProperty
|
|
17
|
+
import java.util.regex.Pattern
|
|
18
|
+
|
|
19
|
+
/**
|
|
20
|
+
* Class responsible for applying the properties to the LottieView.
|
|
21
|
+
* The way react-native works makes it impossible to predict in which order properties will be set,
|
|
22
|
+
* also some of the properties of the LottieView needs to be set simultaneously.
|
|
23
|
+
*
|
|
24
|
+
* To solve this, instance of this class accumulates all changes to the view and applies them at
|
|
25
|
+
* the end of react transaction, so it could control how changes are applied.
|
|
26
|
+
*/
|
|
27
|
+
class LottieAnimationViewPropertyManager(view: LottieAnimationView) {
|
|
28
|
+
private val viewWeakReference: WeakReference<LottieAnimationView>
|
|
29
|
+
|
|
30
|
+
/**
|
|
31
|
+
* Should be set to true if one of the animationName related parameters has changed as a result
|
|
32
|
+
* of last reconciliation. We need to update the animation in this case.
|
|
33
|
+
*/
|
|
34
|
+
private var animationNameDirty = false
|
|
35
|
+
|
|
36
|
+
var animationName: String? = null
|
|
37
|
+
set(value) {
|
|
38
|
+
field = value
|
|
39
|
+
this.animationNameDirty = true
|
|
40
|
+
}
|
|
41
|
+
var scaleType: ImageView.ScaleType? = null
|
|
42
|
+
var imageAssetsFolder: String? = null
|
|
43
|
+
var enableMergePaths: Boolean? = null
|
|
44
|
+
var colorFilters: ReadableArray? = null
|
|
45
|
+
var textFilters: ReadableArray? = null
|
|
46
|
+
var renderMode: RenderMode? = null
|
|
47
|
+
var layerType: Int? = null
|
|
48
|
+
var animationJson: String? = null
|
|
49
|
+
var progress: Float? = null
|
|
50
|
+
var loop: Boolean? = null
|
|
51
|
+
var speed: Float? = null
|
|
52
|
+
|
|
53
|
+
init {
|
|
54
|
+
viewWeakReference = WeakReference(view)
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
/**
|
|
58
|
+
* Updates the view with changed fields.
|
|
59
|
+
* Majority of the properties here are independent so they are has to be reset to null
|
|
60
|
+
* as soon as view is updated with the value.
|
|
61
|
+
*
|
|
62
|
+
* The only exception from this rule is the group of the properties for the animation.
|
|
63
|
+
* For now this is animationName and cacheStrategy. These two properties are should be set
|
|
64
|
+
* simultaneously if the dirty flag is set.
|
|
65
|
+
*/
|
|
66
|
+
fun commitChanges() {
|
|
67
|
+
val view = viewWeakReference.get() ?: return
|
|
68
|
+
|
|
69
|
+
textFilters?.let {
|
|
70
|
+
if(it.size() > 0) {
|
|
71
|
+
val textDelegate = TextDelegate(view)
|
|
72
|
+
for (i in 0 until textFilters!!.size()) {
|
|
73
|
+
val current = textFilters!!.getMap(i)
|
|
74
|
+
val searchText = current.getString("find")
|
|
75
|
+
val replacementText = current.getString("replace")
|
|
76
|
+
textDelegate.setText(searchText, replacementText)
|
|
77
|
+
}
|
|
78
|
+
view.setTextDelegate(textDelegate)
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
animationJson?.let {
|
|
83
|
+
view.setAnimationFromJson(it, it.hashCode().toString())
|
|
84
|
+
animationJson = null
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
if (animationNameDirty) {
|
|
88
|
+
view.setAnimation(animationName)
|
|
89
|
+
animationNameDirty = false
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
progress?.let {
|
|
93
|
+
view.progress = it
|
|
94
|
+
progress = null
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
loop?.let {
|
|
98
|
+
view.repeatCount = if (it) LottieDrawable.INFINITE else 0
|
|
99
|
+
loop = null
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
speed?.let {
|
|
103
|
+
view.speed = it
|
|
104
|
+
speed = null
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
scaleType?.let {
|
|
108
|
+
view.scaleType = it
|
|
109
|
+
scaleType = null
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
renderMode?.let {
|
|
113
|
+
view.renderMode = it
|
|
114
|
+
renderMode = null
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
layerType?.let {
|
|
118
|
+
view.setLayerType(it, null)
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
imageAssetsFolder?.let {
|
|
122
|
+
view.imageAssetsFolder = it
|
|
123
|
+
imageAssetsFolder = null
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
enableMergePaths?.let {
|
|
127
|
+
view.enableMergePathsForKitKatAndAbove(it)
|
|
128
|
+
enableMergePaths = null
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
colorFilters?.let {
|
|
132
|
+
if (it.size() > 0) {
|
|
133
|
+
for (i in 0 until it.size()) {
|
|
134
|
+
val current = it.getMap(i)
|
|
135
|
+
|
|
136
|
+
val color: Int = if (current.getType("color") == ReadableType.Map) {
|
|
137
|
+
ColorPropConverter.getColor(current.getMap("color"), view.context)
|
|
138
|
+
} else {
|
|
139
|
+
current.getInt("color")
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
val path = current.getString("keypath")
|
|
143
|
+
val pathWithGlobStar = "$path.**"
|
|
144
|
+
|
|
145
|
+
val colorFilter: ColorFilter = SimpleColorFilter(color)
|
|
146
|
+
val callback = LottieValueCallback(colorFilter)
|
|
147
|
+
|
|
148
|
+
val keys = pathWithGlobStar.split(Pattern.quote(".")).toTypedArray()
|
|
149
|
+
val keyPath = KeyPath(*keys)
|
|
150
|
+
|
|
151
|
+
view.addValueCallback(keyPath, LottieProperty.COLOR_FILTER, callback)
|
|
152
|
+
}
|
|
153
|
+
}
|
|
154
|
+
}
|
|
155
|
+
}
|
|
156
|
+
}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
package com.airbnb.android.react.lottie
|
|
2
|
+
|
|
3
|
+
import com.facebook.react.ReactPackage
|
|
4
|
+
import com.facebook.react.bridge.NativeModule
|
|
5
|
+
import com.facebook.react.bridge.ReactApplicationContext
|
|
6
|
+
import com.facebook.react.uimanager.ViewManager
|
|
7
|
+
|
|
8
|
+
@Suppress("unused")
|
|
9
|
+
class LottiePackage : ReactPackage {
|
|
10
|
+
|
|
11
|
+
override fun createNativeModules(reactContext: ReactApplicationContext): List<NativeModule> {
|
|
12
|
+
return emptyList()
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
override fun createViewManagers(reactContext: ReactApplicationContext): List<ViewManager<*, *>> {
|
|
16
|
+
return listOf(LottieAnimationViewManager())
|
|
17
|
+
}
|
|
18
|
+
}
|