react-native-screens 3.33.0 → 3.34.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
|
@@ -5,6 +5,7 @@ import android.util.Log
|
|
|
5
5
|
import android.view.View
|
|
6
6
|
import androidx.appcompat.widget.Toolbar
|
|
7
7
|
import androidx.coordinatorlayout.widget.CoordinatorLayout
|
|
8
|
+
import com.facebook.react.bridge.LifecycleEventListener
|
|
8
9
|
import com.facebook.react.bridge.ReactApplicationContext
|
|
9
10
|
import com.facebook.react.uimanager.PixelUtil
|
|
10
11
|
import com.google.android.material.appbar.AppBarLayout
|
|
@@ -19,7 +20,7 @@ import java.lang.ref.WeakReference
|
|
|
19
20
|
*/
|
|
20
21
|
internal class ScreenDummyLayoutHelper(
|
|
21
22
|
reactContext: ReactApplicationContext,
|
|
22
|
-
) {
|
|
23
|
+
) : LifecycleEventListener {
|
|
23
24
|
// The state required to compute header dimensions. We want this on instance rather than on class
|
|
24
25
|
// for context access & being tied to instance lifetime.
|
|
25
26
|
private lateinit var coordinatorLayout: CoordinatorLayout
|
|
@@ -39,7 +40,6 @@ internal class ScreenDummyLayoutHelper(
|
|
|
39
40
|
WeakReference(reactContext)
|
|
40
41
|
|
|
41
42
|
init {
|
|
42
|
-
|
|
43
43
|
// We load the library so that we are able to communicate with our C++ code (descriptor & shadow nodes).
|
|
44
44
|
// Basically we leak this object to C++, as its lifecycle should span throughout whole application
|
|
45
45
|
// lifecycle anyway.
|
|
@@ -50,16 +50,25 @@ internal class ScreenDummyLayoutHelper(
|
|
|
50
50
|
}
|
|
51
51
|
|
|
52
52
|
weakInstance = WeakReference(this)
|
|
53
|
-
|
|
53
|
+
|
|
54
|
+
if (!(reactContext.hasCurrentActivity() && maybeInitDummyLayoutWithHeader(reactContext))) {
|
|
55
|
+
reactContext.addLifecycleEventListener(this)
|
|
56
|
+
}
|
|
54
57
|
}
|
|
55
58
|
|
|
56
59
|
/**
|
|
57
60
|
* Initializes dummy view hierarchy with CoordinatorLayout, AppBarLayout and dummy View.
|
|
58
61
|
* We utilize this to compute header height (app bar layout height) from C++ layer when its needed.
|
|
62
|
+
*
|
|
63
|
+
* @return boolean whether the layout was initialised or not
|
|
59
64
|
*/
|
|
60
|
-
private fun
|
|
61
|
-
if (
|
|
62
|
-
return
|
|
65
|
+
private fun maybeInitDummyLayoutWithHeader(reactContext: ReactApplicationContext): Boolean {
|
|
66
|
+
if (isLayoutInitialized) {
|
|
67
|
+
return true
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
if (!reactContext.hasCurrentActivity()) {
|
|
71
|
+
return false
|
|
63
72
|
}
|
|
64
73
|
|
|
65
74
|
// We need to use activity here, as react context does not have theme attributes required by
|
|
@@ -108,6 +117,9 @@ internal class ScreenDummyLayoutHelper(
|
|
|
108
117
|
addView(appBarLayout)
|
|
109
118
|
addView(dummyContentView)
|
|
110
119
|
}
|
|
120
|
+
|
|
121
|
+
isLayoutInitialized = true
|
|
122
|
+
return true
|
|
111
123
|
}
|
|
112
124
|
|
|
113
125
|
/**
|
|
@@ -121,12 +133,18 @@ internal class ScreenDummyLayoutHelper(
|
|
|
121
133
|
fontSize: Int,
|
|
122
134
|
isTitleEmpty: Boolean,
|
|
123
135
|
): Float {
|
|
124
|
-
if (
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
136
|
+
if (!isLayoutInitialized) {
|
|
137
|
+
val reactContext =
|
|
138
|
+
requireReactContext { "[RNScreens] Context was null-ed before dummy layout was initialized" }
|
|
139
|
+
if (!maybeInitDummyLayoutWithHeader(reactContext)) {
|
|
140
|
+
// This theoretically might happen at Fabric + "bridgefull" combination, due to race condition where `reactContext.currentActivity`
|
|
141
|
+
// is still null at this execution point. We don't wanna crash in such case, thus returning zeroed height.
|
|
142
|
+
Log.e(
|
|
143
|
+
TAG,
|
|
144
|
+
"[RNScreens] Failed to late-init layout while computing header height. This is a race-condition-bug in react-native-screens, please file an issue at https://github.com/software-mansion/react-native-screens/issues"
|
|
145
|
+
)
|
|
146
|
+
return 0.0f
|
|
147
|
+
}
|
|
130
148
|
}
|
|
131
149
|
|
|
132
150
|
if (cache.hasKey(CacheKey(fontSize, isTitleEmpty))) {
|
|
@@ -168,10 +186,10 @@ internal class ScreenDummyLayoutHelper(
|
|
|
168
186
|
return headerHeight
|
|
169
187
|
}
|
|
170
188
|
|
|
171
|
-
private fun requireReactContext(): ReactApplicationContext =
|
|
172
|
-
requireNotNull(
|
|
173
|
-
|
|
174
|
-
|
|
189
|
+
private fun requireReactContext(lazyMessage: (() -> Any)? = null): ReactApplicationContext =
|
|
190
|
+
requireNotNull(
|
|
191
|
+
reactContextRef.get(),
|
|
192
|
+
lazyMessage ?: { "[RNScreens] Attempt to require missing react context" })
|
|
175
193
|
|
|
176
194
|
private fun requireActivity(): Activity =
|
|
177
195
|
requireNotNull(requireReactContext().currentActivity) {
|
|
@@ -195,6 +213,19 @@ internal class ScreenDummyLayoutHelper(
|
|
|
195
213
|
@JvmStatic
|
|
196
214
|
fun getInstance(): ScreenDummyLayoutHelper? = weakInstance.get()
|
|
197
215
|
}
|
|
216
|
+
|
|
217
|
+
private var isLayoutInitialized = false
|
|
218
|
+
|
|
219
|
+
override fun onHostResume() {
|
|
220
|
+
// This is the earliest we have guarantee that the context has a reference to an activity.
|
|
221
|
+
val reactContext = requireReactContext { "[RNScreens] ReactContext missing in onHostResume! This should not happen." }
|
|
222
|
+
check(maybeInitDummyLayoutWithHeader(reactContext)) { "[RNScreens] Failed to initialise dummy layout in onHostResume. This is not expected."}
|
|
223
|
+
reactContext.removeLifecycleEventListener(this)
|
|
224
|
+
}
|
|
225
|
+
|
|
226
|
+
override fun onHostPause() = Unit
|
|
227
|
+
|
|
228
|
+
override fun onHostDestroy() = Unit
|
|
198
229
|
}
|
|
199
230
|
|
|
200
231
|
private data class CacheKey(
|
package/package.json
CHANGED