Skip to content

Commit 56e5dff

Browse files
lunaleapsfacebook-github-bot
authored andcommitted
Hysteresis window for VirtualViewExperimental (#53765)
Summary: Pull Request resolved: #53765 Changelog: [Internal] Introduce hysteresis window for experimental VirtualView Reviewed By: yungsters Differential Revision: D82354142 fbshipit-source-id: 13ec0e3a46930d3bea0ea67060c5f0e1c137dec1
1 parent 4f20e4d commit 56e5dff

File tree

2 files changed

+25
-7
lines changed

2 files changed

+25
-7
lines changed

packages/react-native/ReactAndroid/src/main/java/com/facebook/react/views/scroll/VirtualViewContainer.kt

Lines changed: 24 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -50,11 +50,13 @@ private fun rectsOverlap(rect1: Rect, rect2: Rect): Boolean {
5050
internal class VirtualViewContainerState {
5151

5252
private val prerenderRatio: Double = ReactNativeFeatureFlags.virtualViewPrerenderRatio()
53+
private val hysteresisRatio: Double = ReactNativeFeatureFlags.virtualViewHysteresisRatio()
5354

5455
private val virtualViews: MutableSet<VirtualView> = mutableSetOf()
5556
private val emptyRect: Rect = Rect()
5657
private val visibleRect: Rect = Rect()
5758
private val prerenderRect: Rect = Rect()
59+
private val hysteresisRect: Rect = Rect()
5860
private val onWindowFocusChangeListener =
5961
if (ReactNativeFeatureFlags.enableVirtualViewWindowFocusDetection()) {
6062
ViewTreeObserver.OnWindowFocusChangeListener {
@@ -124,7 +126,7 @@ internal class VirtualViewContainerState {
124126
virtualViewsIt.forEach { vv ->
125127
val rect = vv.containerRelativeRect
126128

127-
var mode = VirtualViewMode.Hidden
129+
var mode: VirtualViewMode? = VirtualViewMode.Hidden
128130
var thresholdRect = emptyRect
129131
when {
130132
rectsOverlap(rect, visibleRect) -> {
@@ -143,14 +145,29 @@ internal class VirtualViewContainerState {
143145
mode = VirtualViewMode.Prerender
144146
thresholdRect = prerenderRect
145147
}
146-
else -> {}
148+
else -> {
149+
if (hysteresisRatio > 0.0) {
150+
hysteresisRect.set(prerenderRect)
151+
hysteresisRect.inset(
152+
(-visibleRect.width() * hysteresisRatio).toInt(),
153+
(-visibleRect.height() * hysteresisRatio).toInt(),
154+
)
155+
if (rectsOverlap(rect, hysteresisRect)) {
156+
mode = null
157+
}
158+
}
159+
}
147160
}
148161

149-
debugLog(
150-
"updateModes",
151-
{ "virtualView=${vv.virtualViewID} mode=$mode rect=$rect thresholdRect=$thresholdRect" },
152-
)
153-
vv.onModeChange(mode, thresholdRect)
162+
if (mode != null) {
163+
vv.onModeChange(mode, thresholdRect)
164+
debugLog(
165+
"updateModes",
166+
{
167+
"virtualView=${vv.virtualViewID} mode=$mode rect=$rect thresholdRect=$thresholdRect"
168+
},
169+
)
170+
}
154171
}
155172
}
156173
}

packages/react-native/ReactAndroid/src/main/java/com/facebook/react/views/virtual/viewexperimental/ReactVirtualViewExperimental.kt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ import com.facebook.react.uimanager.ReactClippingViewGroup
2020
import com.facebook.react.uimanager.ReactRoot
2121
import com.facebook.react.views.scroll.VirtualView
2222
import com.facebook.react.views.scroll.VirtualViewContainer
23+
import com.facebook.react.views.scroll.debugLog
2324
import com.facebook.react.views.view.ReactViewGroup
2425
import com.facebook.react.views.virtual.VirtualViewMode
2526
import com.facebook.react.views.virtual.VirtualViewModeChangeEmitter

0 commit comments

Comments
 (0)