@@ -9,6 +9,7 @@ package com.facebook.react.views.scroll
9
9
10
10
import android.graphics.Rect
11
11
import android.view.ViewGroup
12
+ import android.view.ViewTreeObserver
12
13
import com.facebook.common.logging.FLog
13
14
import com.facebook.react.common.build.ReactBuildConfig
14
15
import com.facebook.react.internal.featureflags.ReactNativeFeatureFlags
@@ -46,13 +47,34 @@ private fun rectsOverlap(rect1: Rect, rect2: Rect): Boolean {
46
47
return true
47
48
}
48
49
49
- internal class VirtualViewContainerState ( private val scrollView : ViewGroup ) {
50
+ internal class VirtualViewContainerState {
50
51
51
52
private val prerenderRatio: Double = ReactNativeFeatureFlags .virtualViewPrerenderRatio()
53
+ private val detectWindowFocus = ReactNativeFeatureFlags .enableVirtualViewWindowFocusDetection()
54
+
52
55
private val virtualViews: MutableSet <VirtualView > = mutableSetOf ()
53
56
private val emptyRect: Rect = Rect ()
54
57
private val visibleRect: Rect = Rect ()
55
58
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
+ }
56
78
57
79
public fun onChange (virtualView : VirtualView ) {
58
80
if (virtualViews.add(virtualView)) {
@@ -72,7 +94,7 @@ internal class VirtualViewContainerState(private val scrollView: ViewGroup) {
72
94
73
95
// Called on ScrollView onLayout or onScroll
74
96
public fun updateState () {
75
- debugLog(" VirtualViewContainer. updateState" )
97
+ debugLog(" updateState" )
76
98
updateModes()
77
99
}
78
100
@@ -92,8 +114,16 @@ internal class VirtualViewContainerState(private val scrollView: ViewGroup) {
92
114
when {
93
115
rect.isEmpty -> {}
94
116
rectsOverlap(rect, visibleRect) -> {
95
- mode = VirtualViewMode .Visible
96
117
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
+ }
97
127
}
98
128
rectsOverlap(rect, prerenderRect) -> {
99
129
mode = VirtualViewMode .Prerender
0 commit comments