diff --git a/dotlottie/build.gradle.kts b/dotlottie/build.gradle.kts index 895473f..bfe133f 100644 --- a/dotlottie/build.gradle.kts +++ b/dotlottie/build.gradle.kts @@ -37,7 +37,7 @@ dotlottieRust { } group = "com.github.LottieFiles" -version = "0.14.0" +version = "0.14.1" android { namespace = "com.lottiefiles.dotlottie.core" diff --git a/dotlottie/src/main/java/com/lottiefiles/dotlottie/core/widget/DotLottieAnimation.kt b/dotlottie/src/main/java/com/lottiefiles/dotlottie/core/widget/DotLottieAnimation.kt index 5a4e758..cbbdeeb 100644 --- a/dotlottie/src/main/java/com/lottiefiles/dotlottie/core/widget/DotLottieAnimation.kt +++ b/dotlottie/src/main/java/com/lottiefiles/dotlottie/core/widget/DotLottieAnimation.kt @@ -35,6 +35,7 @@ import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.Job import kotlinx.coroutines.SupervisorJob import kotlinx.coroutines.cancel +import kotlinx.coroutines.isActive import kotlinx.coroutines.launch import kotlinx.coroutines.withContext import com.dotlottie.dlplayer.Config as DLConfig @@ -70,7 +71,7 @@ class DotLottieAnimation @JvmOverloads constructor( private var height: Int = 0 private var mConfig: Config? = null private var mLottieDrawable: DotLottieDrawable? = null - private val coroutineScope = CoroutineScope(SupervisorJob()) + private var coroutineScope = CoroutineScope(SupervisorJob()) private var setupConfigJob: Job? = null private var setupDrawableJob: Job? = null private var layoutListener: ViewTreeObserver.OnGlobalLayoutListener? = null @@ -337,8 +338,8 @@ class DotLottieAnimation @JvmOverloads constructor( layoutListener = object : ViewTreeObserver.OnGlobalLayoutListener { override fun onGlobalLayout() { if (width > 0 && height > 0) { - // Start animation setup only when dimensions are available - setupDotLottieDrawable() + // Start animation setup only when dimensions are available. + setupDrawableIfNeeded() // Remove the listener to avoid redundant calls removeLayoutListener() } @@ -365,8 +366,24 @@ class DotLottieAnimation @JvmOverloads constructor( } + private fun ensureScopeActive() { + if (!coroutineScope.isActive) { + coroutineScope = CoroutineScope(SupervisorJob()) + } + } + + private fun setupDrawableIfNeeded() { + if (mLottieDrawable != null) return + if (setupConfigJob?.isActive == true || setupDrawableJob?.isActive == true) return + when { + mConfig != null -> setupConfig() + ::attributes.isInitialized && attributes.src.isNotBlank() -> setupDotLottieDrawable() + } + } + private fun setupConfig() { val config = mConfig ?: return + ensureScopeActive() setupConfigJob?.cancel() setupConfigJob = coroutineScope.launch { runCatching { @@ -416,6 +433,7 @@ class DotLottieAnimation @JvmOverloads constructor( } private fun setupDotLottieDrawable() { + ensureScopeActive() setupDrawableJob?.cancel() setupDrawableJob = coroutineScope.launch { runCatching { @@ -426,6 +444,8 @@ class DotLottieAnimation @JvmOverloads constructor( DotLottieUtils.getContent(context, DotLottieSource.Asset(attributes.src)) } + if (!isActive || !this@DotLottieAnimation.isAttachedToWindow) return@launch + mLottieDrawable = DotLottieDrawable( animationData = content, width = width, @@ -482,6 +502,17 @@ class DotLottieAnimation @JvmOverloads constructor( } } + override fun onAttachedToWindow() { + super.onAttachedToWindow() + if (mLottieDrawable == null) { + if (width > 0 && height > 0) { + setupDrawableIfNeeded() + } else if (layoutListener == null) { + waitForLayout() + } + } + } + override fun onDetachedFromWindow() { super.onDetachedFromWindow() removeLayoutListener()