react-native-screens 3.32.0 → 3.33.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.
- package/README.md +17 -13
- package/RNScreens.podspec +10 -52
- package/android/CMakeLists.txt +48 -4
- package/android/build.gradle +9 -81
- package/android/src/fabric/java/com/swmansion/rnscreens/FabricEnabledViewGroup.kt +25 -16
- package/android/src/fabric/java/com/swmansion/rnscreens/NativeProxy.kt +53 -0
- package/android/src/main/cpp/NativeProxy.cpp +51 -0
- package/android/src/main/cpp/NativeProxy.h +35 -0
- package/android/src/main/cpp/OnLoad.cpp +8 -0
- package/android/src/main/java/com/swmansion/rnscreens/CustomSearchView.kt +5 -2
- package/android/src/main/java/com/swmansion/rnscreens/CustomToolbar.kt +4 -1
- package/android/src/main/java/com/swmansion/rnscreens/FragmentBackPressOverrider.kt +2 -2
- package/android/src/main/java/com/swmansion/rnscreens/RNScreensPackage.kt +36 -17
- package/android/src/main/java/com/swmansion/rnscreens/Screen.kt +134 -38
- package/android/src/main/java/com/swmansion/rnscreens/ScreenContainer.kt +52 -30
- package/android/src/main/java/com/swmansion/rnscreens/ScreenContainerViewManager.kt +17 -7
- package/android/src/main/java/com/swmansion/rnscreens/ScreenEventDispatcher.kt +10 -2
- package/android/src/main/java/com/swmansion/rnscreens/ScreenFragment.kt +56 -27
- package/android/src/main/java/com/swmansion/rnscreens/ScreenFragmentWrapper.kt +8 -1
- package/android/src/main/java/com/swmansion/rnscreens/ScreenStack.kt +50 -19
- package/android/src/main/java/com/swmansion/rnscreens/ScreenStackFragment.kt +60 -37
- package/android/src/main/java/com/swmansion/rnscreens/ScreenStackFragmentWrapper.kt +4 -0
- package/android/src/main/java/com/swmansion/rnscreens/ScreenStackHeaderConfig.kt +85 -58
- package/android/src/main/java/com/swmansion/rnscreens/ScreenStackHeaderConfigViewManager.kt +128 -37
- package/android/src/main/java/com/swmansion/rnscreens/ScreenStackHeaderSubview.kt +19 -4
- package/android/src/main/java/com/swmansion/rnscreens/ScreenStackHeaderSubviewManager.kt +16 -10
- package/android/src/main/java/com/swmansion/rnscreens/ScreenStackViewManager.kt +28 -25
- package/android/src/main/java/com/swmansion/rnscreens/ScreenViewManager.kt +173 -78
- package/android/src/main/java/com/swmansion/rnscreens/ScreenWindowTraits.kt +59 -24
- package/android/src/main/java/com/swmansion/rnscreens/ScreensModule.kt +30 -8
- package/android/src/main/java/com/swmansion/rnscreens/ScreensShadowNode.kt +3 -1
- package/android/src/main/java/com/swmansion/rnscreens/SearchBarManager.kt +101 -50
- package/android/src/main/java/com/swmansion/rnscreens/SearchBarView.kt +29 -22
- package/android/src/main/java/com/swmansion/rnscreens/SearchViewFormatter.kt +7 -2
- package/android/src/main/java/com/swmansion/rnscreens/events/HeaderAttachedEvent.kt +4 -1
- package/android/src/main/java/com/swmansion/rnscreens/events/HeaderBackButtonClickedEvent.kt +4 -1
- package/android/src/main/java/com/swmansion/rnscreens/events/HeaderDetachedEvent.kt +4 -1
- package/android/src/main/java/com/swmansion/rnscreens/events/HeaderHeightChangeEvent.kt +5 -5
- package/android/src/main/java/com/swmansion/rnscreens/events/ScreenAppearEvent.kt +4 -1
- package/android/src/main/java/com/swmansion/rnscreens/events/ScreenDisappearEvent.kt +4 -1
- package/android/src/main/java/com/swmansion/rnscreens/events/ScreenDismissedEvent.kt +8 -4
- package/android/src/main/java/com/swmansion/rnscreens/events/ScreenTransitionProgressEvent.kt +7 -6
- package/android/src/main/java/com/swmansion/rnscreens/events/ScreenWillAppearEvent.kt +4 -1
- package/android/src/main/java/com/swmansion/rnscreens/events/ScreenWillDisappearEvent.kt +4 -1
- package/android/src/main/java/com/swmansion/rnscreens/events/SearchBarBlurEvent.kt +4 -1
- package/android/src/main/java/com/swmansion/rnscreens/events/SearchBarChangeTextEvent.kt +4 -3
- package/android/src/main/java/com/swmansion/rnscreens/events/SearchBarCloseEvent.kt +4 -1
- package/android/src/main/java/com/swmansion/rnscreens/events/SearchBarFocusEvent.kt +4 -1
- package/android/src/main/java/com/swmansion/rnscreens/events/SearchBarOpenEvent.kt +4 -1
- package/android/src/main/java/com/swmansion/rnscreens/events/SearchBarSearchButtonPressEvent.kt +9 -4
- package/android/src/main/java/com/swmansion/rnscreens/events/StackFinishTransitioningEvent.kt +4 -1
- package/android/src/main/java/com/swmansion/rnscreens/utils/DeviceUtils.kt +1 -5
- package/android/src/main/java/com/swmansion/rnscreens/utils/ScreenDummyLayoutHelper.kt +214 -0
- package/android/src/main/jni/CMakeLists.txt +5 -4
- package/android/src/paper/java/com/facebook/react/viewmanagers/RNSScreenManagerDelegate.java +3 -0
- package/android/src/paper/java/com/facebook/react/viewmanagers/RNSScreenManagerInterface.java +1 -0
- package/android/src/paper/java/com/swmansion/rnscreens/FabricEnabledViewGroup.kt +10 -5
- package/android/src/paper/java/com/swmansion/rnscreens/NativeProxy.kt +19 -0
- package/android/src/paper/java/com/swmansion/rnscreens/NativeScreensModuleSpec.java +4 -0
- package/common/cpp/react/renderer/components/rnscreens/FrameCorrectionModes.h +51 -0
- package/common/cpp/react/renderer/components/rnscreens/RNSModalScreenShadowNode.cpp +2 -1
- package/common/cpp/react/renderer/components/rnscreens/RNSModalScreenShadowNode.h +1 -1
- package/common/cpp/react/renderer/components/rnscreens/RNSScreenComponentDescriptor.h +140 -1
- package/common/cpp/react/renderer/components/rnscreens/RNSScreenShadowNode.cpp +51 -1
- package/common/cpp/react/renderer/components/rnscreens/RNSScreenShadowNode.h +23 -1
- package/common/cpp/react/renderer/components/rnscreens/RNSScreenState.cpp +20 -0
- package/common/cpp/react/renderer/components/rnscreens/RNSScreenState.h +23 -1
- package/common/cpp/react/renderer/components/rnscreens/utils/RectUtil.h +36 -0
- package/cpp/RNSScreenRemovalListener.cpp +25 -0
- package/cpp/RNSScreenRemovalListener.h +20 -0
- package/ios/RNSConvert.h +1 -0
- package/ios/RNSModalScreen.mm +22 -0
- package/ios/RNSModule.mm +1 -1
- package/ios/RNSScreen.h +2 -1
- package/ios/RNSScreen.mm +27 -19
- package/ios/RNSScreenStack.mm +24 -77
- package/ios/RNSScreenStackAnimator.mm +43 -6
- package/ios/RNSScreenStackHeaderConfig.mm +49 -11
- package/ios/RNSScreenStackHeaderSubview.mm +8 -0
- package/ios/utils/UIView+RNSUtility.h +23 -0
- package/ios/utils/UIView+RNSUtility.mm +55 -0
- package/lib/commonjs/components/ScreenStack.js +8 -1
- package/lib/commonjs/components/ScreenStack.js.map +1 -1
- package/lib/commonjs/fabric/ModalScreenNativeComponent.js.map +1 -1
- package/lib/commonjs/fabric/ScreenNativeComponent.js.map +1 -1
- package/lib/commonjs/native-stack/views/NativeStackView.js +2 -0
- package/lib/commonjs/native-stack/views/NativeStackView.js.map +1 -1
- package/lib/module/components/ScreenStack.js +8 -1
- package/lib/module/components/ScreenStack.js.map +1 -1
- package/lib/module/fabric/ModalScreenNativeComponent.js.map +1 -1
- package/lib/module/fabric/ScreenNativeComponent.js.map +1 -1
- package/lib/module/native-stack/views/NativeStackView.js +2 -0
- package/lib/module/native-stack/views/NativeStackView.js.map +1 -1
- package/lib/typescript/components/ScreenStack.d.ts.map +1 -1
- package/lib/typescript/fabric/ModalScreenNativeComponent.d.ts +1 -0
- package/lib/typescript/fabric/ModalScreenNativeComponent.d.ts.map +1 -1
- package/lib/typescript/fabric/ScreenNativeComponent.d.ts +1 -0
- package/lib/typescript/fabric/ScreenNativeComponent.d.ts.map +1 -1
- package/lib/typescript/native-stack/types.d.ts +10 -0
- package/lib/typescript/native-stack/types.d.ts.map +1 -1
- package/lib/typescript/native-stack/views/NativeStackView.d.ts.map +1 -1
- package/lib/typescript/types.d.ts +10 -0
- package/lib/typescript/types.d.ts.map +1 -1
- package/native-stack/README.md +110 -99
- package/package.json +6 -3
- package/react-native.config.js +17 -15
- package/src/TransitionProgressContext.tsx +1 -1
- package/src/components/Screen.tsx +4 -4
- package/src/components/ScreenStack.tsx +11 -1
- package/src/components/ScreenStackHeaderConfig.tsx +5 -5
- package/src/components/ScreenStackHeaderConfig.web.tsx +6 -6
- package/src/components/SearchBar.tsx +4 -4
- package/src/core.ts +1 -1
- package/src/fabric/ModalScreenNativeComponent.ts +1 -0
- package/src/fabric/ScreenNativeComponent.ts +1 -0
- package/src/fabric/ScreenNavigationContainerNativeComponent.ts +1 -1
- package/src/fabric/ScreenStackHeaderConfigNativeComponent.ts +1 -1
- package/src/fabric/ScreenStackHeaderSubviewNativeComponent.ts +1 -1
- package/src/fabric/SearchBarNativeComponent.ts +1 -1
- package/src/gesture-handler/ScreenGestureDetector.tsx +5 -5
- package/src/gesture-handler/constraints.ts +5 -5
- package/src/gesture-handler/fabricUtils.ts +1 -1
- package/src/native-stack/contexts/GHContext.tsx +1 -1
- package/src/native-stack/navigators/createNativeStackNavigator.tsx +3 -3
- package/src/native-stack/types.tsx +14 -4
- package/src/native-stack/utils/getDefaultHeaderHeight.tsx +1 -1
- package/src/native-stack/utils/getStatusBarHeight.tsx +1 -1
- package/src/native-stack/utils/useAnimatedHeaderHeight.tsx +1 -1
- package/src/native-stack/utils/useBackPressSubscription.tsx +1 -1
- package/src/native-stack/utils/useHeaderHeight.tsx +1 -1
- package/src/native-stack/views/FontProcessor.tsx +1 -1
- package/src/native-stack/views/HeaderConfig.tsx +1 -1
- package/src/native-stack/views/NativeStackView.tsx +11 -9
- package/src/reanimated/ReanimatedHeaderHeightContext.tsx +1 -1
- package/src/reanimated/ReanimatedNativeStackScreen.tsx +5 -5
- package/src/reanimated/ReanimatedScreen.tsx +2 -2
- package/src/reanimated/ReanimatedScreenProvider.tsx +1 -1
- package/src/reanimated/useReanimatedHeaderHeight.tsx +1 -1
- package/src/reanimated/useReanimatedTransitionProgress.tsx +1 -1
- package/src/types.tsx +15 -5
- package/src/useTransitionProgress.tsx +1 -1
- package/windows/README.md +4 -1
|
@@ -4,7 +4,10 @@ import com.facebook.react.bridge.Arguments
|
|
|
4
4
|
import com.facebook.react.bridge.WritableMap
|
|
5
5
|
import com.facebook.react.uimanager.events.Event
|
|
6
6
|
|
|
7
|
-
class SearchBarCloseEvent(
|
|
7
|
+
class SearchBarCloseEvent(
|
|
8
|
+
surfaceId: Int,
|
|
9
|
+
viewId: Int,
|
|
10
|
+
) : Event<SearchBarCloseEvent>(surfaceId, viewId) {
|
|
8
11
|
override fun getEventName(): String = EVENT_NAME
|
|
9
12
|
|
|
10
13
|
// All events for a given view can be coalesced.
|
|
@@ -4,7 +4,10 @@ import com.facebook.react.bridge.Arguments
|
|
|
4
4
|
import com.facebook.react.bridge.WritableMap
|
|
5
5
|
import com.facebook.react.uimanager.events.Event
|
|
6
6
|
|
|
7
|
-
class SearchBarFocusEvent(
|
|
7
|
+
class SearchBarFocusEvent(
|
|
8
|
+
surfaceId: Int,
|
|
9
|
+
viewId: Int,
|
|
10
|
+
) : Event<SearchBarFocusEvent>(surfaceId, viewId) {
|
|
8
11
|
override fun getEventName(): String = EVENT_NAME
|
|
9
12
|
|
|
10
13
|
// All events for a given view can be coalesced.
|
|
@@ -4,7 +4,10 @@ import com.facebook.react.bridge.Arguments
|
|
|
4
4
|
import com.facebook.react.bridge.WritableMap
|
|
5
5
|
import com.facebook.react.uimanager.events.Event
|
|
6
6
|
|
|
7
|
-
class SearchBarOpenEvent(
|
|
7
|
+
class SearchBarOpenEvent(
|
|
8
|
+
surfaceId: Int,
|
|
9
|
+
viewId: Int,
|
|
10
|
+
) : Event<SearchBarOpenEvent>(surfaceId, viewId) {
|
|
8
11
|
override fun getEventName(): String = EVENT_NAME
|
|
9
12
|
|
|
10
13
|
// All events for a given view can be coalesced.
|
package/android/src/main/java/com/swmansion/rnscreens/events/SearchBarSearchButtonPressEvent.kt
CHANGED
|
@@ -4,15 +4,20 @@ import com.facebook.react.bridge.Arguments
|
|
|
4
4
|
import com.facebook.react.bridge.WritableMap
|
|
5
5
|
import com.facebook.react.uimanager.events.Event
|
|
6
6
|
|
|
7
|
-
class SearchBarSearchButtonPressEvent(
|
|
7
|
+
class SearchBarSearchButtonPressEvent(
|
|
8
|
+
surfaceId: Int,
|
|
9
|
+
viewId: Int,
|
|
10
|
+
private val text: String?,
|
|
11
|
+
) : Event<SearchBarSearchButtonPressEvent>(surfaceId, viewId) {
|
|
8
12
|
override fun getEventName(): String = EVENT_NAME
|
|
9
13
|
|
|
10
14
|
// All events for a given view can be coalesced.
|
|
11
15
|
override fun getCoalescingKey(): Short = 0
|
|
12
16
|
|
|
13
|
-
override fun getEventData(): WritableMap? =
|
|
14
|
-
|
|
15
|
-
|
|
17
|
+
override fun getEventData(): WritableMap? =
|
|
18
|
+
Arguments.createMap().apply {
|
|
19
|
+
putString("text", text)
|
|
20
|
+
}
|
|
16
21
|
|
|
17
22
|
companion object {
|
|
18
23
|
const val EVENT_NAME = "topSearchButtonPress"
|
package/android/src/main/java/com/swmansion/rnscreens/events/StackFinishTransitioningEvent.kt
CHANGED
|
@@ -4,7 +4,10 @@ import com.facebook.react.bridge.Arguments
|
|
|
4
4
|
import com.facebook.react.bridge.WritableMap
|
|
5
5
|
import com.facebook.react.uimanager.events.Event
|
|
6
6
|
|
|
7
|
-
class StackFinishTransitioningEvent(
|
|
7
|
+
class StackFinishTransitioningEvent(
|
|
8
|
+
surfaceId: Int,
|
|
9
|
+
viewId: Int,
|
|
10
|
+
) : Event<StackFinishTransitioningEvent>(surfaceId, viewId) {
|
|
8
11
|
override fun getEventName() = EVENT_NAME
|
|
9
12
|
|
|
10
13
|
// All events for a given view can be coalesced.
|
|
@@ -4,9 +4,5 @@ import android.content.Context
|
|
|
4
4
|
import android.content.pm.PackageManager
|
|
5
5
|
|
|
6
6
|
object DeviceUtils {
|
|
7
|
-
|
|
8
|
-
fun isPlatformAndroidTV(context: Context?): Boolean {
|
|
9
|
-
return context?.packageManager?.hasSystemFeature(PackageManager.FEATURE_LEANBACK) == true
|
|
10
|
-
}
|
|
11
|
-
|
|
7
|
+
fun isPlatformAndroidTV(context: Context?): Boolean = context?.packageManager?.hasSystemFeature(PackageManager.FEATURE_LEANBACK) == true
|
|
12
8
|
}
|
|
@@ -0,0 +1,214 @@
|
|
|
1
|
+
package com.swmansion.rnscreens.utils
|
|
2
|
+
|
|
3
|
+
import android.app.Activity
|
|
4
|
+
import android.util.Log
|
|
5
|
+
import android.view.View
|
|
6
|
+
import androidx.appcompat.widget.Toolbar
|
|
7
|
+
import androidx.coordinatorlayout.widget.CoordinatorLayout
|
|
8
|
+
import com.facebook.react.bridge.ReactApplicationContext
|
|
9
|
+
import com.facebook.react.uimanager.PixelUtil
|
|
10
|
+
import com.google.android.material.appbar.AppBarLayout
|
|
11
|
+
import com.swmansion.rnscreens.ScreenStackHeaderConfig
|
|
12
|
+
import java.lang.ref.WeakReference
|
|
13
|
+
|
|
14
|
+
/**
|
|
15
|
+
* This class provides methods to create dummy layout (that mimics Screen setup), and to compute
|
|
16
|
+
* expected header height. It is meant to be accessed from C++ layer via JNI.
|
|
17
|
+
* See https://github.com/software-mansion/react-native-screens/pull/2169
|
|
18
|
+
* for more detailed description of the issue this code solves.
|
|
19
|
+
*/
|
|
20
|
+
internal class ScreenDummyLayoutHelper(
|
|
21
|
+
reactContext: ReactApplicationContext,
|
|
22
|
+
) {
|
|
23
|
+
// The state required to compute header dimensions. We want this on instance rather than on class
|
|
24
|
+
// for context access & being tied to instance lifetime.
|
|
25
|
+
private lateinit var coordinatorLayout: CoordinatorLayout
|
|
26
|
+
private lateinit var appBarLayout: AppBarLayout
|
|
27
|
+
private lateinit var dummyContentView: View
|
|
28
|
+
private lateinit var toolbar: Toolbar
|
|
29
|
+
private var defaultFontSize: Float = 0f
|
|
30
|
+
private var defaultContentInsetStartWithNavigation: Int = 0
|
|
31
|
+
|
|
32
|
+
// LRU with size 1
|
|
33
|
+
private var cache: CacheEntry = CacheEntry.EMPTY
|
|
34
|
+
|
|
35
|
+
// We do not want to be responsible for the context lifecycle. If it's null, we're fine.
|
|
36
|
+
// This same context is being passed down to our view components so it is destroyed
|
|
37
|
+
// only if our views also are.
|
|
38
|
+
private var reactContextRef: WeakReference<ReactApplicationContext> =
|
|
39
|
+
WeakReference(reactContext)
|
|
40
|
+
|
|
41
|
+
init {
|
|
42
|
+
|
|
43
|
+
// We load the library so that we are able to communicate with our C++ code (descriptor & shadow nodes).
|
|
44
|
+
// Basically we leak this object to C++, as its lifecycle should span throughout whole application
|
|
45
|
+
// lifecycle anyway.
|
|
46
|
+
try {
|
|
47
|
+
System.loadLibrary(LIBRARY_NAME)
|
|
48
|
+
} catch (e: UnsatisfiedLinkError) {
|
|
49
|
+
Log.w(TAG, "Failed to load $LIBRARY_NAME")
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
weakInstance = WeakReference(this)
|
|
53
|
+
ensureDummyLayoutWithHeader(reactContext)
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
/**
|
|
57
|
+
* Initializes dummy view hierarchy with CoordinatorLayout, AppBarLayout and dummy View.
|
|
58
|
+
* We utilize this to compute header height (app bar layout height) from C++ layer when its needed.
|
|
59
|
+
*/
|
|
60
|
+
private fun ensureDummyLayoutWithHeader(reactContext: ReactApplicationContext) {
|
|
61
|
+
if (::coordinatorLayout.isInitialized) {
|
|
62
|
+
return
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
// We need to use activity here, as react context does not have theme attributes required by
|
|
66
|
+
// AppBarLayout attached leading to crash.
|
|
67
|
+
val contextWithTheme =
|
|
68
|
+
requireNotNull(reactContext.currentActivity) { "[RNScreens] Attempt to use context detached from activity" }
|
|
69
|
+
|
|
70
|
+
coordinatorLayout = CoordinatorLayout(contextWithTheme)
|
|
71
|
+
|
|
72
|
+
appBarLayout =
|
|
73
|
+
AppBarLayout(contextWithTheme).apply {
|
|
74
|
+
layoutParams =
|
|
75
|
+
CoordinatorLayout.LayoutParams(
|
|
76
|
+
CoordinatorLayout.LayoutParams.MATCH_PARENT,
|
|
77
|
+
CoordinatorLayout.LayoutParams.WRAP_CONTENT,
|
|
78
|
+
)
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
toolbar =
|
|
82
|
+
Toolbar(contextWithTheme).apply {
|
|
83
|
+
title = DEFAULT_HEADER_TITLE
|
|
84
|
+
layoutParams =
|
|
85
|
+
AppBarLayout
|
|
86
|
+
.LayoutParams(
|
|
87
|
+
AppBarLayout.LayoutParams.MATCH_PARENT,
|
|
88
|
+
AppBarLayout.LayoutParams.WRAP_CONTENT,
|
|
89
|
+
).apply { scrollFlags = 0 }
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
// We know the title text view will be there, cause we've just set title.
|
|
93
|
+
defaultFontSize = ScreenStackHeaderConfig.findTitleTextViewInToolbar(toolbar)!!.textSize
|
|
94
|
+
defaultContentInsetStartWithNavigation = toolbar.contentInsetStartWithNavigation
|
|
95
|
+
|
|
96
|
+
appBarLayout.addView(toolbar)
|
|
97
|
+
|
|
98
|
+
dummyContentView =
|
|
99
|
+
View(contextWithTheme).apply {
|
|
100
|
+
layoutParams =
|
|
101
|
+
CoordinatorLayout.LayoutParams(
|
|
102
|
+
CoordinatorLayout.LayoutParams.MATCH_PARENT,
|
|
103
|
+
CoordinatorLayout.LayoutParams.MATCH_PARENT,
|
|
104
|
+
)
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
coordinatorLayout.apply {
|
|
108
|
+
addView(appBarLayout)
|
|
109
|
+
addView(dummyContentView)
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
/**
|
|
114
|
+
* Triggers layout pass on dummy view hierarchy, taking into consideration selected
|
|
115
|
+
* ScreenStackHeaderConfig props that might have impact on final header height.
|
|
116
|
+
*
|
|
117
|
+
* @param fontSize font size value as passed from JS
|
|
118
|
+
* @return header height in dp as consumed by Yoga
|
|
119
|
+
*/
|
|
120
|
+
private fun computeDummyLayout(
|
|
121
|
+
fontSize: Int,
|
|
122
|
+
isTitleEmpty: Boolean,
|
|
123
|
+
): Float {
|
|
124
|
+
if (!::coordinatorLayout.isInitialized) {
|
|
125
|
+
Log.e(
|
|
126
|
+
TAG,
|
|
127
|
+
"[RNScreens] Attempt to access dummy view hierarchy before it is initialized",
|
|
128
|
+
)
|
|
129
|
+
return 0.0f
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
if (cache.hasKey(CacheKey(fontSize, isTitleEmpty))) {
|
|
133
|
+
return cache.headerHeight
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
val topLevelDecorView = requireActivity().window.decorView
|
|
137
|
+
|
|
138
|
+
// These dimensions are not accurate, as they do include status bar & navigation bar, however
|
|
139
|
+
// it is ok for our purposes.
|
|
140
|
+
val decorViewWidth = topLevelDecorView.width
|
|
141
|
+
val decorViewHeight = topLevelDecorView.height
|
|
142
|
+
|
|
143
|
+
val widthMeasureSpec =
|
|
144
|
+
View.MeasureSpec.makeMeasureSpec(decorViewWidth, View.MeasureSpec.EXACTLY)
|
|
145
|
+
val heightMeasureSpec =
|
|
146
|
+
View.MeasureSpec.makeMeasureSpec(decorViewHeight, View.MeasureSpec.EXACTLY)
|
|
147
|
+
|
|
148
|
+
if (isTitleEmpty) {
|
|
149
|
+
toolbar.title = ""
|
|
150
|
+
toolbar.contentInsetStartWithNavigation = 0
|
|
151
|
+
} else {
|
|
152
|
+
toolbar.title = DEFAULT_HEADER_TITLE
|
|
153
|
+
toolbar.contentInsetStartWithNavigation = defaultContentInsetStartWithNavigation
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
val textView = ScreenStackHeaderConfig.findTitleTextViewInToolbar(toolbar)
|
|
157
|
+
textView?.textSize =
|
|
158
|
+
if (fontSize != FONT_SIZE_UNSET) fontSize.toFloat() else defaultFontSize
|
|
159
|
+
|
|
160
|
+
coordinatorLayout.measure(widthMeasureSpec, heightMeasureSpec)
|
|
161
|
+
|
|
162
|
+
// It seems that measure pass would be enough, however I'm not certain whether there are no
|
|
163
|
+
// scenarios when layout violates measured dimensions.
|
|
164
|
+
coordinatorLayout.layout(0, 0, decorViewWidth, decorViewHeight)
|
|
165
|
+
|
|
166
|
+
val headerHeight = PixelUtil.toDIPFromPixel(appBarLayout.height.toFloat())
|
|
167
|
+
cache = CacheEntry(CacheKey(fontSize, isTitleEmpty), headerHeight)
|
|
168
|
+
return headerHeight
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
private fun requireReactContext(): ReactApplicationContext =
|
|
172
|
+
requireNotNull(reactContextRef.get()) {
|
|
173
|
+
"[RNScreens] Attempt to require missing react context"
|
|
174
|
+
}
|
|
175
|
+
|
|
176
|
+
private fun requireActivity(): Activity =
|
|
177
|
+
requireNotNull(requireReactContext().currentActivity) {
|
|
178
|
+
"[RNScreens] Attempt to use context detached from activity"
|
|
179
|
+
}
|
|
180
|
+
|
|
181
|
+
companion object {
|
|
182
|
+
const val TAG = "ScreenDummyLayoutHelper"
|
|
183
|
+
|
|
184
|
+
const val LIBRARY_NAME = "react_codegen_rnscreens"
|
|
185
|
+
|
|
186
|
+
const val FONT_SIZE_UNSET = -1
|
|
187
|
+
|
|
188
|
+
private const val DEFAULT_HEADER_TITLE: String = "FontSize123!#$"
|
|
189
|
+
|
|
190
|
+
// We access this field from C++ layer, through `getInstance` method.
|
|
191
|
+
// We don't care what instance we get access to as long as it has initialized
|
|
192
|
+
// dummy view hierarchy.
|
|
193
|
+
private var weakInstance = WeakReference<ScreenDummyLayoutHelper>(null)
|
|
194
|
+
|
|
195
|
+
@JvmStatic
|
|
196
|
+
fun getInstance(): ScreenDummyLayoutHelper? = weakInstance.get()
|
|
197
|
+
}
|
|
198
|
+
}
|
|
199
|
+
|
|
200
|
+
private data class CacheKey(
|
|
201
|
+
val fontSize: Int,
|
|
202
|
+
val isTitleEmpty: Boolean,
|
|
203
|
+
)
|
|
204
|
+
|
|
205
|
+
private class CacheEntry(
|
|
206
|
+
val cacheKey: CacheKey,
|
|
207
|
+
val headerHeight: Float,
|
|
208
|
+
) {
|
|
209
|
+
fun hasKey(key: CacheKey) = cacheKey.fontSize != Int.MIN_VALUE && cacheKey == key
|
|
210
|
+
|
|
211
|
+
companion object {
|
|
212
|
+
val EMPTY = CacheEntry(CacheKey(Int.MIN_VALUE, false), 0f)
|
|
213
|
+
}
|
|
214
|
+
}
|
|
@@ -6,6 +6,7 @@ set(LIB_TARGET_NAME react_codegen_${LIB_LITERAL})
|
|
|
6
6
|
|
|
7
7
|
set(LIB_ANDROID_DIR ${CMAKE_CURRENT_SOURCE_DIR}/../../..)
|
|
8
8
|
set(LIB_COMMON_DIR ${LIB_ANDROID_DIR}/../common/cpp)
|
|
9
|
+
set(LIB_COMMON_COMPONENTS_DIR ${LIB_COMMON_DIR}/react/renderer/components/${LIB_LITERAL})
|
|
9
10
|
set(LIB_ANDROID_GENERATED_JNI_DIR ${LIB_ANDROID_DIR}/build/generated/source/codegen/jni)
|
|
10
11
|
set(LIB_ANDROID_GENERATED_COMPONENTS_DIR ${LIB_ANDROID_GENERATED_JNI_DIR}/react/renderer/components/${LIB_LITERAL})
|
|
11
12
|
|
|
@@ -18,20 +19,20 @@ add_compile_options(
|
|
|
18
19
|
-Wno-gnu-zero-variadic-macro-arguments
|
|
19
20
|
)
|
|
20
21
|
|
|
21
|
-
file(GLOB LIB_CUSTOM_SRCS CONFIGURE_DEPENDS *.cpp ${
|
|
22
|
+
file(GLOB LIB_CUSTOM_SRCS CONFIGURE_DEPENDS *.cpp ${LIB_COMMON_COMPONENTS_DIR}/*.cpp ${LIB_COMMON_COMPONENTS_DIR}/utils/*.cpp)
|
|
22
23
|
file(GLOB LIB_CODEGEN_SRCS CONFIGURE_DEPENDS ${LIB_ANDROID_GENERATED_COMPONENTS_DIR}/*.cpp)
|
|
23
24
|
|
|
24
25
|
add_library(
|
|
25
26
|
${LIB_TARGET_NAME}
|
|
26
|
-
SHARED
|
|
27
|
+
SHARED
|
|
27
28
|
${LIB_CUSTOM_SRCS}
|
|
28
29
|
${LIB_CODEGEN_SRCS}
|
|
29
30
|
)
|
|
30
31
|
|
|
31
32
|
target_include_directories(
|
|
32
33
|
${LIB_TARGET_NAME}
|
|
33
|
-
PUBLIC
|
|
34
|
-
.
|
|
34
|
+
PUBLIC
|
|
35
|
+
.
|
|
35
36
|
${LIB_COMMON_DIR}
|
|
36
37
|
${LIB_ANDROID_GENERATED_JNI_DIR}
|
|
37
38
|
${LIB_ANDROID_GENERATED_COMPONENTS_DIR}
|
package/android/src/paper/java/com/facebook/react/viewmanagers/RNSScreenManagerDelegate.java
CHANGED
|
@@ -44,6 +44,9 @@ public class RNSScreenManagerDelegate<T extends View, U extends BaseViewManagerI
|
|
|
44
44
|
case "fullScreenSwipeEnabled":
|
|
45
45
|
mViewManager.setFullScreenSwipeEnabled(view, value == null ? false : (boolean) value);
|
|
46
46
|
break;
|
|
47
|
+
case "fullScreenSwipeShadowEnabled":
|
|
48
|
+
mViewManager.setFullScreenSwipeShadowEnabled(view, value == null ? false : (boolean) value);
|
|
49
|
+
break;
|
|
47
50
|
case "homeIndicatorHidden":
|
|
48
51
|
mViewManager.setHomeIndicatorHidden(view, value == null ? false : (boolean) value);
|
|
49
52
|
break;
|
package/android/src/paper/java/com/facebook/react/viewmanagers/RNSScreenManagerInterface.java
CHANGED
|
@@ -21,6 +21,7 @@ public interface RNSScreenManagerInterface<T extends View> {
|
|
|
21
21
|
void setSheetExpandsWhenScrolledToEdge(T view, boolean value);
|
|
22
22
|
void setCustomAnimationOnSwipe(T view, boolean value);
|
|
23
23
|
void setFullScreenSwipeEnabled(T view, boolean value);
|
|
24
|
+
void setFullScreenSwipeShadowEnabled(T view, boolean value);
|
|
24
25
|
void setHomeIndicatorHidden(T view, boolean value);
|
|
25
26
|
void setPreventNativeDismiss(T view, boolean value);
|
|
26
27
|
void setGestureEnabled(T view, boolean value);
|
|
@@ -2,13 +2,18 @@ package com.swmansion.rnscreens
|
|
|
2
2
|
|
|
3
3
|
import android.view.ViewGroup
|
|
4
4
|
import com.facebook.react.bridge.ReactContext
|
|
5
|
-
import com.facebook.react.uimanager.
|
|
5
|
+
import com.facebook.react.uimanager.StateWrapper
|
|
6
6
|
|
|
7
|
-
abstract class FabricEnabledViewGroup
|
|
7
|
+
abstract class FabricEnabledViewGroup(
|
|
8
|
+
context: ReactContext?,
|
|
9
|
+
) : ViewGroup(context) {
|
|
10
|
+
fun setStateWrapper(wrapper: StateWrapper?) = Unit
|
|
8
11
|
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
+
protected fun updateScreenSizeFabric(
|
|
13
|
+
width: Int,
|
|
14
|
+
height: Int,
|
|
15
|
+
headerHeight: Double,
|
|
16
|
+
) {
|
|
12
17
|
// do nothing
|
|
13
18
|
}
|
|
14
19
|
}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
package com.swmansion.rnscreens
|
|
2
|
+
|
|
3
|
+
import com.facebook.react.fabric.FabricUIManager
|
|
4
|
+
|
|
5
|
+
class NativeProxy {
|
|
6
|
+
// do nothing on Paper
|
|
7
|
+
fun nativeAddMutationsListener(fabricUIManager: FabricUIManager) = Unit
|
|
8
|
+
|
|
9
|
+
companion object {
|
|
10
|
+
fun addScreenToMap(
|
|
11
|
+
tag: Int,
|
|
12
|
+
view: Screen,
|
|
13
|
+
) = Unit
|
|
14
|
+
|
|
15
|
+
fun removeScreenFromMap(tag: Int) = Unit
|
|
16
|
+
|
|
17
|
+
fun clearMapOnInvalidate() = Unit
|
|
18
|
+
}
|
|
19
|
+
}
|
|
@@ -12,8 +12,10 @@
|
|
|
12
12
|
|
|
13
13
|
package com.swmansion.rnscreens;
|
|
14
14
|
|
|
15
|
+
import com.facebook.proguard.annotations.DoNotStrip;
|
|
15
16
|
import com.facebook.react.bridge.ReactApplicationContext;
|
|
16
17
|
import com.facebook.react.bridge.ReactContextBaseJavaModule;
|
|
18
|
+
import com.facebook.react.bridge.ReactMethod;
|
|
17
19
|
import com.facebook.react.bridge.ReactModuleWithSpec;
|
|
18
20
|
import com.facebook.react.turbomodule.core.interfaces.TurboModule;
|
|
19
21
|
import javax.annotation.Nonnull;
|
|
@@ -29,4 +31,6 @@ public abstract class NativeScreensModuleSpec extends ReactContextBaseJavaModule
|
|
|
29
31
|
public @Nonnull String getName() {
|
|
30
32
|
return NAME;
|
|
31
33
|
}
|
|
34
|
+
|
|
35
|
+
|
|
32
36
|
}
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
#pragma once
|
|
2
|
+
|
|
3
|
+
#include <cstdint>
|
|
4
|
+
|
|
5
|
+
namespace rnscreens {
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* Flags describing types of corrections to apply to Screen frame
|
|
9
|
+
* after layout process.
|
|
10
|
+
*/
|
|
11
|
+
class FrameCorrectionModes final {
|
|
12
|
+
public:
|
|
13
|
+
enum Mode : std::uint8_t {
|
|
14
|
+
/**
|
|
15
|
+
* No correction should be applied to layout metrics of Screen
|
|
16
|
+
*/
|
|
17
|
+
None = 0,
|
|
18
|
+
|
|
19
|
+
/**
|
|
20
|
+
* Screen's frame height should be corrected
|
|
21
|
+
*/
|
|
22
|
+
FrameHeightCorrection = 1 << 0,
|
|
23
|
+
|
|
24
|
+
/**
|
|
25
|
+
* Screen's frame origin should be corrected
|
|
26
|
+
*/
|
|
27
|
+
FrameOriginCorrection = 1 << 1,
|
|
28
|
+
};
|
|
29
|
+
|
|
30
|
+
inline void set(Mode mode) {
|
|
31
|
+
modes_ = Mode(modes_ | mode);
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
inline void unset(Mode mode) {
|
|
35
|
+
modes_ = Mode(modes_ & ~mode);
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
// Check whether current set of flags contains all flags set in argument.
|
|
39
|
+
inline bool check(Mode mode) const {
|
|
40
|
+
return Mode(modes_ & mode) == mode;
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
inline Mode getAll() const {
|
|
44
|
+
return modes_;
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
private:
|
|
48
|
+
Mode modes_{Mode::None};
|
|
49
|
+
};
|
|
50
|
+
|
|
51
|
+
} // namespace rnscreens
|
|
@@ -5,7 +5,8 @@ namespace react {
|
|
|
5
5
|
|
|
6
6
|
extern const char RNSModalScreenComponentName[] = "RNSModalScreen";
|
|
7
7
|
|
|
8
|
-
Point RNSModalScreenShadowNode::getContentOriginOffset(
|
|
8
|
+
Point RNSModalScreenShadowNode::getContentOriginOffset(
|
|
9
|
+
bool /*includeTransform*/) const {
|
|
9
10
|
auto stateData = getStateData();
|
|
10
11
|
auto contentOffset = stateData.contentOffset;
|
|
11
12
|
return {contentOffset.x, contentOffset.y};
|
|
@@ -20,7 +20,7 @@ class JSI_EXPORT RNSModalScreenShadowNode final
|
|
|
20
20
|
public:
|
|
21
21
|
using ConcreteViewShadowNode::ConcreteViewShadowNode;
|
|
22
22
|
|
|
23
|
-
Point getContentOriginOffset() const override;
|
|
23
|
+
Point getContentOriginOffset(bool includeTransform) const override;
|
|
24
24
|
static ShadowNodeTraits BaseTraits() {
|
|
25
25
|
auto traits = ConcreteViewShadowNode::BaseTraits();
|
|
26
26
|
traits.set(ShadowNodeTraits::Trait::RootNodeKind);
|
|
@@ -1,17 +1,27 @@
|
|
|
1
1
|
#pragma once
|
|
2
2
|
|
|
3
|
+
#ifdef ANDROID
|
|
4
|
+
#include <fbjni/fbjni.h>
|
|
5
|
+
#endif
|
|
3
6
|
#include <react/debug/react_native_assert.h>
|
|
7
|
+
#include <react/renderer/components/rnscreens/Props.h>
|
|
4
8
|
#include <react/renderer/core/ConcreteComponentDescriptor.h>
|
|
5
9
|
#include "RNSScreenShadowNode.h"
|
|
10
|
+
#include "utils/RectUtil.h"
|
|
6
11
|
|
|
7
12
|
namespace facebook {
|
|
8
13
|
namespace react {
|
|
9
14
|
|
|
15
|
+
using namespace rnscreens;
|
|
16
|
+
|
|
10
17
|
class RNSScreenComponentDescriptor final
|
|
11
18
|
: public ConcreteComponentDescriptor<RNSScreenShadowNode> {
|
|
12
19
|
public:
|
|
13
20
|
using ConcreteComponentDescriptor::ConcreteComponentDescriptor;
|
|
14
21
|
|
|
22
|
+
static constexpr const char *kScreenDummyLayoutHelperClass =
|
|
23
|
+
"com/swmansion/rnscreens/utils/ScreenDummyLayoutHelper";
|
|
24
|
+
|
|
15
25
|
void adopt(ShadowNode &shadowNode) const override {
|
|
16
26
|
react_native_assert(dynamic_cast<RNSScreenShadowNode *>(&shadowNode));
|
|
17
27
|
auto &screenShadowNode = static_cast<RNSScreenShadowNode &>(shadowNode);
|
|
@@ -26,13 +36,142 @@ class RNSScreenComponentDescriptor final
|
|
|
26
36
|
shadowNode.getState());
|
|
27
37
|
auto stateData = state->getData();
|
|
28
38
|
|
|
39
|
+
#ifdef ANDROID
|
|
29
40
|
if (stateData.frameSize.width != 0 && stateData.frameSize.height != 0) {
|
|
41
|
+
// When we receive dimensions from JVM side we can remove padding used for
|
|
42
|
+
// correction, and we can stop applying height correction for the frame.
|
|
43
|
+
// We want to leave top offset correction though intact.
|
|
44
|
+
// TODO: In future, when we have dynamic header height we might want to
|
|
45
|
+
// update Y offset correction here.
|
|
46
|
+
|
|
47
|
+
#ifdef REACT_NATIVE_DEBUG
|
|
48
|
+
// We use the fact that height correction is disabled once we receive
|
|
49
|
+
// state from the native, so when we have incoming state & height
|
|
50
|
+
// correction is still enabled, we know this is the very first native
|
|
51
|
+
// state update.
|
|
52
|
+
if (screenShadowNode.getFrameCorrectionModes().check(
|
|
53
|
+
FrameCorrectionModes::Mode::FrameHeightCorrection) &&
|
|
54
|
+
!checkFrameSizesEqualWithEps(
|
|
55
|
+
screenShadowNode.layoutMetrics_.frame.size,
|
|
56
|
+
stateData.frameSize)) {
|
|
57
|
+
LOG(ERROR)
|
|
58
|
+
<< "[RNScreens] The first frame received from state update: "
|
|
59
|
+
<< stateData.frameSize.width << "x" << stateData.frameSize.height
|
|
60
|
+
<< " differs from the one expected: "
|
|
61
|
+
<< screenShadowNode.layoutMetrics_.frame.size.width << "x"
|
|
62
|
+
<< screenShadowNode.layoutMetrics_.frame.size.height
|
|
63
|
+
<< ". This is most likely a react-native-screens library bug. Please report this at https://github.com/software-mansion/react-native-screens/issues";
|
|
64
|
+
}
|
|
65
|
+
#endif
|
|
66
|
+
|
|
67
|
+
screenShadowNode.setPadding({0, 0, 0, 0});
|
|
68
|
+
screenShadowNode.getFrameCorrectionModes().unset(
|
|
69
|
+
FrameCorrectionModes::Mode::FrameHeightCorrection);
|
|
70
|
+
|
|
30
71
|
layoutableShadowNode.setSize(
|
|
31
72
|
Size{stateData.frameSize.width, stateData.frameSize.height});
|
|
32
|
-
}
|
|
73
|
+
} else {
|
|
74
|
+
// This code path should be executed only on the very first (few)
|
|
75
|
+
// layout(s), when we haven't received state update from JVM side yet.
|
|
76
|
+
|
|
77
|
+
auto headerConfigChildOpt = findHeaderConfigChild(layoutableShadowNode);
|
|
78
|
+
|
|
79
|
+
// During creation of the shadow node children are not attached yet.
|
|
80
|
+
// We also do not want to set any padding in case.
|
|
81
|
+
if (headerConfigChildOpt) {
|
|
82
|
+
const auto &headerConfigChild = headerConfigChildOpt->get();
|
|
83
|
+
const auto &headerProps =
|
|
84
|
+
*std::static_pointer_cast<const RNSScreenStackHeaderConfigProps>(
|
|
85
|
+
headerConfigChild->getProps());
|
|
86
|
+
|
|
87
|
+
const auto headerHeight = headerProps.hidden
|
|
88
|
+
? 0.f
|
|
89
|
+
: findHeaderHeight(
|
|
90
|
+
headerProps.titleFontSize, headerProps.title.empty())
|
|
91
|
+
.value_or(0.f);
|
|
33
92
|
|
|
93
|
+
screenShadowNode.setPadding({0, 0, 0, headerHeight});
|
|
94
|
+
screenShadowNode.setHeaderHeight(headerHeight);
|
|
95
|
+
screenShadowNode.getFrameCorrectionModes().set(
|
|
96
|
+
FrameCorrectionModes::Mode(
|
|
97
|
+
FrameCorrectionModes::Mode::FrameHeightCorrection |
|
|
98
|
+
FrameCorrectionModes::Mode::FrameOriginCorrection));
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
#else
|
|
102
|
+
if (stateData.frameSize.width != 0 && stateData.frameSize.height != 0) {
|
|
103
|
+
layoutableShadowNode.setSize(
|
|
104
|
+
Size{stateData.frameSize.width, stateData.frameSize.height});
|
|
105
|
+
}
|
|
106
|
+
#endif // ANDROID
|
|
34
107
|
ConcreteComponentDescriptor::adopt(shadowNode);
|
|
35
108
|
}
|
|
109
|
+
|
|
110
|
+
std::optional<std::reference_wrapper<const ShadowNode::Shared>>
|
|
111
|
+
findHeaderConfigChild(
|
|
112
|
+
const YogaLayoutableShadowNode &screenShadowNode) const {
|
|
113
|
+
for (const ShadowNode::Shared &child : screenShadowNode.getChildren()) {
|
|
114
|
+
if (std::strcmp(
|
|
115
|
+
child->getComponentName(), "RNSScreenStackHeaderConfig") == 0) {
|
|
116
|
+
return {std::cref(child)};
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
return {};
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
#ifdef ANDROID
|
|
123
|
+
std::optional<float> findHeaderHeight(
|
|
124
|
+
const int fontSize,
|
|
125
|
+
const bool isTitleEmpty) const {
|
|
126
|
+
JNIEnv *env = facebook::jni::Environment::current();
|
|
127
|
+
|
|
128
|
+
if (env == nullptr) {
|
|
129
|
+
LOG(ERROR) << "[RNScreens] Failed to retrieve env\n";
|
|
130
|
+
return {};
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
jclass layoutHelperClass = env->FindClass(kScreenDummyLayoutHelperClass);
|
|
134
|
+
|
|
135
|
+
if (layoutHelperClass == nullptr) {
|
|
136
|
+
LOG(ERROR) << "[RNScreens] Failed to find class with id "
|
|
137
|
+
<< kScreenDummyLayoutHelperClass;
|
|
138
|
+
return {};
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
jmethodID computeDummyLayoutID =
|
|
142
|
+
env->GetMethodID(layoutHelperClass, "computeDummyLayout", "(IZ)F");
|
|
143
|
+
|
|
144
|
+
if (computeDummyLayoutID == nullptr) {
|
|
145
|
+
LOG(ERROR)
|
|
146
|
+
<< "[RNScreens] Failed to retrieve computeDummyLayout method ID";
|
|
147
|
+
return {};
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
jmethodID getInstanceMethodID = env->GetStaticMethodID(
|
|
151
|
+
layoutHelperClass,
|
|
152
|
+
"getInstance",
|
|
153
|
+
"()Lcom/swmansion/rnscreens/utils/ScreenDummyLayoutHelper;");
|
|
154
|
+
|
|
155
|
+
if (getInstanceMethodID == nullptr) {
|
|
156
|
+
LOG(ERROR) << "[RNScreens] Failed to retrieve getInstanceMethodID";
|
|
157
|
+
return {};
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
jobject packageInstance =
|
|
161
|
+
env->CallStaticObjectMethod(layoutHelperClass, getInstanceMethodID);
|
|
162
|
+
|
|
163
|
+
if (packageInstance == nullptr) {
|
|
164
|
+
LOG(ERROR)
|
|
165
|
+
<< "[RNScreens] Failed to retrieve packageInstance or the package instance was null on JVM side";
|
|
166
|
+
return {};
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
jfloat headerHeight = env->CallFloatMethod(
|
|
170
|
+
packageInstance, computeDummyLayoutID, fontSize, isTitleEmpty);
|
|
171
|
+
|
|
172
|
+
return {headerHeight};
|
|
173
|
+
}
|
|
174
|
+
#endif // ANDROID
|
|
36
175
|
};
|
|
37
176
|
|
|
38
177
|
} // namespace react
|