From 00fbc6a709f092af46eddb3c73858fef08b4dfe6 Mon Sep 17 00:00:00 2001 From: i-ts Date: Wed, 19 Nov 2025 11:29:54 +0300 Subject: [PATCH] use local resolver when tracking items visibility inside gallery commit_hash:c5bc972fd7ecf062b11e529d0b0387c36c46ee26 --- .../core/view2/DivVisibilityActionTracker.kt | 9 +++++++-- .../core/view2/divs/BaseDivViewExtensions.kt | 19 ++++++++++++++++++- .../divs/gallery/DivGalleryScrollListener.kt | 11 ++++++++++- 3 files changed, 35 insertions(+), 4 deletions(-) diff --git a/client/android/div/src/main/java/com/yandex/div/core/view2/DivVisibilityActionTracker.kt b/client/android/div/src/main/java/com/yandex/div/core/view2/DivVisibilityActionTracker.kt index fd151b54b..19c3bfbe8 100644 --- a/client/android/div/src/main/java/com/yandex/div/core/view2/DivVisibilityActionTracker.kt +++ b/client/android/div/src/main/java/com/yandex/div/core/view2/DivVisibilityActionTracker.kt @@ -13,6 +13,7 @@ import com.yandex.div.core.util.SynchronizedWeakHashMap import com.yandex.div.core.util.allAppearActions import com.yandex.div.core.util.allDisappearActions import com.yandex.div.core.util.doOnHierarchyLayout +import com.yandex.div.core.view2.divs.bindingContext import com.yandex.div.core.view2.divs.duration import com.yandex.div.internal.Assert import com.yandex.div.internal.KAssert @@ -156,7 +157,8 @@ internal class DivVisibilityActionTracker @Inject constructor( } else { previousVisibilityIsFull[currentView] = isViewFullyVisible currentDiv?.let { - trackVisibilityActionsOf(context.divView, context.expressionResolver, currentView, it) + val ctx = currentView.bindingContext ?: context + trackVisibilityActionsOf(context.divView, ctx.expressionResolver, currentView, it) } true } @@ -166,7 +168,10 @@ internal class DivVisibilityActionTracker @Inject constructor( fun cancelTrackingViewsHierarchy(context: BindingContext, root: View, div: Div?) { trackViewsHierarchy(context, root, div) { currentView, currentDiv -> previousVisibilityIsFull.remove(currentView) - currentDiv?.let { trackVisibilityActionsOf(context.divView, context.expressionResolver, null, it) } + currentDiv?.let { + val ctx = currentView.bindingContext ?: context + trackVisibilityActionsOf(context.divView, ctx.expressionResolver, null, it) + } true } } diff --git a/client/android/div/src/main/java/com/yandex/div/core/view2/divs/BaseDivViewExtensions.kt b/client/android/div/src/main/java/com/yandex/div/core/view2/divs/BaseDivViewExtensions.kt index 61144d47b..bfe2c90be 100644 --- a/client/android/div/src/main/java/com/yandex/div/core/view2/divs/BaseDivViewExtensions.kt +++ b/client/android/div/src/main/java/com/yandex/div/core/view2/divs/BaseDivViewExtensions.kt @@ -36,6 +36,7 @@ import com.yandex.div.core.view2.divs.widgets.DivHolderView import com.yandex.div.core.view2.divs.widgets.DivStateLayout import com.yandex.div.core.view2.reuse.InputFocusTracker import com.yandex.div.core.widget.AspectView +import com.yandex.div.core.widget.DivViewWrapper import com.yandex.div.internal.Log import com.yandex.div.internal.core.DivItemBuilderResult import com.yandex.div.internal.core.ExpressionSubscriber @@ -375,7 +376,23 @@ internal fun View.clearFocusOnClick(focusTracker: InputFocusTracker) { focusTracker.removeFocusFromFocusedInput() } -internal val View.bindingContext get() = (this as? DivHolderView<*>)?.bindingContext +internal val View.bindingContext: BindingContext? get() { + (this as? DivHolderView<*>)?.bindingContext?.let { return it } + + val divViewWrapper = this as? DivViewWrapper + ?: return null + + val itemChild: View = divViewWrapper.child + ?: return null + + val divHolderView = itemChild as? DivHolderView<*> + ?: return null + + val context = divHolderView.bindingContext + ?: return null + + return context +} internal fun bindItemBuilder(builder: DivCollectionItemBuilder, resolver: ExpressionResolver, callback: (Any) -> Unit) { builder.data.observe(resolver, callback) diff --git a/client/android/div/src/main/java/com/yandex/div/core/view2/divs/gallery/DivGalleryScrollListener.kt b/client/android/div/src/main/java/com/yandex/div/core/view2/divs/gallery/DivGalleryScrollListener.kt index 970276070..8b0811c7c 100644 --- a/client/android/div/src/main/java/com/yandex/div/core/view2/divs/gallery/DivGalleryScrollListener.kt +++ b/client/android/div/src/main/java/com/yandex/div/core/view2/divs/gallery/DivGalleryScrollListener.kt @@ -1,10 +1,14 @@ package com.yandex.div.core.view2.divs.gallery +import android.view.View import androidx.core.view.children import androidx.recyclerview.widget.RecyclerView import com.yandex.div.core.ScrollDirection import com.yandex.div.core.view2.BindingContext +import com.yandex.div.core.view2.divs.bindingContext +import com.yandex.div.core.view2.divs.widgets.DivHolderView import com.yandex.div.core.view2.divs.widgets.DivRecyclerView +import com.yandex.div.core.widget.DivViewWrapper import com.yandex.div2.DivGallery import kotlin.math.abs @@ -67,7 +71,12 @@ internal class DivGalleryScrollListener( if (position == RecyclerView.NO_POSITION) return@forEach val div = (recycler.adapter as DivGalleryAdapter).visibleItems[position].div - visibilityActionTracker.startTrackingViewsHierarchy(bindingContext, child, div) + + visibilityActionTracker.startTrackingViewsHierarchy( + context = child.bindingContext ?: bindingContext, + root = child, + rootDiv = div, + ) } // Find and track recycled views containing DisappearActions that are waiting for disappear