Skip to content

Commit cf8acc1

Browse files
lunaleapsfacebook-github-bot
authored andcommitted
Implement windowFocus on ReactVirtualViewExperiment (#52690)
Summary: Changelog: [Internal] - Add the window focus experiment to ReactVirtualViewExperimental Reviewed By: yungsters Differential Revision: D78502991
1 parent 4217a7b commit cf8acc1

File tree

2 files changed

+36
-3
lines changed

2 files changed

+36
-3
lines changed

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

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -407,6 +407,9 @@ protected void onDetachedFromWindow() {
407407
if (mMaintainVisibleContentPositionHelper != null) {
408408
mMaintainVisibleContentPositionHelper.stop();
409409
}
410+
if (mVirtualViewContainerState != null) {
411+
mVirtualViewContainerState.cleanup();
412+
}
410413
}
411414

412415
@Override

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

Lines changed: 33 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ package com.facebook.react.views.scroll
99

1010
import android.graphics.Rect
1111
import android.view.ViewGroup
12+
import android.view.ViewTreeObserver
1213
import com.facebook.common.logging.FLog
1314
import com.facebook.react.common.build.ReactBuildConfig
1415
import com.facebook.react.internal.featureflags.ReactNativeFeatureFlags
@@ -46,13 +47,34 @@ private fun rectsOverlap(rect1: Rect, rect2: Rect): Boolean {
4647
return true
4748
}
4849

49-
internal class VirtualViewContainerState(private val scrollView: ViewGroup) {
50+
internal class VirtualViewContainerState {
5051

5152
private val prerenderRatio: Double = ReactNativeFeatureFlags.virtualViewPrerenderRatio()
53+
private val detectWindowFocus = ReactNativeFeatureFlags.enableVirtualViewWindowFocusDetection()
54+
5255
private val virtualViews: MutableSet<VirtualView> = mutableSetOf()
5356
private val emptyRect: Rect = Rect()
5457
private val visibleRect: Rect = Rect()
5558
private val prerenderRect: Rect = Rect()
59+
private val onWindowFocusChangeListener =
60+
ViewTreeObserver.OnWindowFocusChangeListener {
61+
debugLog("onWindowFocusChanged")
62+
updateModes()
63+
}
64+
private val scrollView: ViewGroup
65+
66+
constructor(scrollView: ViewGroup) {
67+
this.scrollView = scrollView
68+
if (detectWindowFocus) {
69+
scrollView.viewTreeObserver.addOnWindowFocusChangeListener(onWindowFocusChangeListener)
70+
}
71+
}
72+
73+
public fun cleanup() {
74+
if (detectWindowFocus) {
75+
scrollView.viewTreeObserver.removeOnWindowFocusChangeListener(onWindowFocusChangeListener)
76+
}
77+
}
5678

5779
public fun onChange(virtualView: VirtualView) {
5880
if (virtualViews.add(virtualView)) {
@@ -72,7 +94,7 @@ internal class VirtualViewContainerState(private val scrollView: ViewGroup) {
7294

7395
// Called on ScrollView onLayout or onScroll
7496
public fun updateState() {
75-
debugLog("VirtualViewContainer.updateState")
97+
debugLog("updateState")
7698
updateModes()
7799
}
78100

@@ -92,8 +114,16 @@ internal class VirtualViewContainerState(private val scrollView: ViewGroup) {
92114
when {
93115
rect.isEmpty -> {}
94116
rectsOverlap(rect, visibleRect) -> {
95-
mode = VirtualViewMode.Visible
96117
thresholdRect = visibleRect
118+
if (detectWindowFocus) {
119+
if (scrollView.hasWindowFocus()) {
120+
mode = VirtualViewMode.Visible
121+
} else {
122+
mode = VirtualViewMode.Prerender
123+
}
124+
} else {
125+
mode = VirtualViewMode.Visible
126+
}
97127
}
98128
rectsOverlap(rect, prerenderRect) -> {
99129
mode = VirtualViewMode.Prerender

0 commit comments

Comments
 (0)