cancel transitions when scene root has detached

commit_hash:db2fa3bb7d4d0861d219cb6b8978d9ad61bf8391
This commit is contained in:
gulevsky
2024-10-25 17:19:52 +03:00
parent c0a118e517
commit a97dd6e4c1
6 changed files with 42 additions and 1 deletions
+1
View File
@@ -1210,6 +1210,7 @@
"client/android/div/src/main/java/com/yandex/div/core/view2/animations/Fade.kt":"divkit/public/client/android/div/src/main/java/com/yandex/div/core/view2/animations/Fade.kt",
"client/android/div/src/main/java/com/yandex/div/core/view2/animations/OutlineAwareVisibility.kt":"divkit/public/client/android/div/src/main/java/com/yandex/div/core/view2/animations/OutlineAwareVisibility.kt",
"client/android/div/src/main/java/com/yandex/div/core/view2/animations/Scale.kt":"divkit/public/client/android/div/src/main/java/com/yandex/div/core/view2/animations/Scale.kt",
"client/android/div/src/main/java/com/yandex/div/core/view2/animations/SceneRootWatcher.kt":"divkit/public/client/android/div/src/main/java/com/yandex/div/core/view2/animations/SceneRootWatcher.kt",
"client/android/div/src/main/java/com/yandex/div/core/view2/animations/Slide.kt":"divkit/public/client/android/div/src/main/java/com/yandex/div/core/view2/animations/Slide.kt",
"client/android/div/src/main/java/com/yandex/div/core/view2/animations/Transitions.kt":"divkit/public/client/android/div/src/main/java/com/yandex/div/core/view2/animations/Transitions.kt",
"client/android/div/src/main/java/com/yandex/div/core/view2/animations/Utils.kt":"divkit/public/client/android/div/src/main/java/com/yandex/div/core/view2/animations/Utils.kt",
+1
View File
@@ -3,6 +3,7 @@
# Android Client:
* Added API to force specific `Div2View` to use canvas clipping.
* Fixed optional expression resolving when default value is defined.
* Fixed running transition behavior when scene root is detached.
# iOS Client:
* Add `isEmpty()` method to dict and array.
@@ -6,6 +6,7 @@ import androidx.transition.TransitionManager
import com.yandex.div.core.animation.SpringInterpolator
import com.yandex.div.core.annotations.PublicApi
import com.yandex.div.core.view2.Div2View
import com.yandex.div.core.view2.animations.SceneRootWatcher
import javax.inject.Provider
@PublicApi
@@ -37,6 +38,7 @@ class DefaultDivStateChangeListener @JvmOverloads constructor(
val rootView = rootViewProvider.get() ?: return
val transition = DivStateTransition(divView).setInterpolator(interpolator)
TransitionManager.endTransitions(rootView)
SceneRootWatcher.watchFor(rootView, transition)
TransitionManager.beginDelayedTransition(rootView, transition)
}
}
@@ -45,6 +45,7 @@ import com.yandex.div.core.util.SingleTimeOnAttachCallback
import com.yandex.div.core.util.walk
import com.yandex.div.core.view2.animations.DivComparator
import com.yandex.div.core.view2.animations.DivTransitionHandler
import com.yandex.div.core.view2.animations.SceneRootWatcher
import com.yandex.div.core.view2.animations.allowsTransitionsOnDataChange
import com.yandex.div.core.view2.animations.doOnEnd
import com.yandex.div.core.view2.divs.DivLayoutProviderVariablesHolder
@@ -877,8 +878,9 @@ class Div2View private constructor(
}
if (transition != null) {
val newStateScene = Scene(this, newStateView)
TransitionManager.endTransitions(this)
val newStateScene = Scene(this, newStateView)
SceneRootWatcher.watchFor(newStateScene, transition)
TransitionManager.go(newStateScene, transition)
} else {
addView(newStateView)
@@ -0,0 +1,33 @@
package com.yandex.div.core.view2.animations
import android.view.View
import android.view.View.OnAttachStateChangeListener
import android.view.ViewGroup
import androidx.transition.Scene
import androidx.transition.Transition
import androidx.transition.TransitionManager
internal object SceneRootWatcher {
fun watchFor(scene: Scene, transition: Transition) {
watchFor(scene.sceneRoot, transition)
}
fun watchFor(sceneRoot: ViewGroup, transition: Transition) {
val detachListener = OnDetachListener(sceneRoot)
sceneRoot.addOnAttachStateChangeListener(detachListener)
transition.doOnEnd { sceneRoot.removeOnAttachStateChangeListener(detachListener) }
}
private class OnDetachListener(
private val sceneRoot: ViewGroup
) : OnAttachStateChangeListener {
override fun onViewAttachedToWindow(view: View) = Unit
override fun onViewDetachedFromWindow(view: View) {
sceneRoot.removeOnAttachStateChangeListener(this)
TransitionManager.endTransitions(sceneRoot)
}
}
}
@@ -32,6 +32,7 @@ import com.yandex.div.core.view2.DivVisibilityActionTracker
import com.yandex.div.core.view2.animations.DivComparator
import com.yandex.div.core.view2.animations.Fade
import com.yandex.div.core.view2.animations.Scale
import com.yandex.div.core.view2.animations.SceneRootWatcher
import com.yandex.div.core.view2.animations.VerticalTranslation
import com.yandex.div.core.view2.animations.allowsTransitionsOnStateChange
import com.yandex.div.core.view2.divs.widgets.DivStateLayout
@@ -132,6 +133,7 @@ internal class DivStateBinder @Inject constructor(
if (transition != null) {
TransitionManager.endTransitions(layout)
SceneRootWatcher.watchFor(layout, transition)
TransitionManager.beginDelayedTransition(layout, transition)
}
layout.releaseAndRemoveChildren(divView)