react-native-screens 4.0.0-beta.0 → 4.0.0-beta.1
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 +1 -1
- package/android/build.gradle +26 -6
- package/android/src/fabric/java/com/swmansion/rnscreens/FabricEnabledViewGroup.kt +4 -3
- package/android/src/main/java/com/swmansion/rnscreens/CustomToolbar.kt +40 -1
- package/android/src/main/java/com/swmansion/rnscreens/Screen.kt +18 -34
- package/android/src/main/java/com/swmansion/rnscreens/ScreenStack.kt +9 -3
- package/android/src/main/java/com/swmansion/rnscreens/ScreenViewManager.kt +2 -1
- package/android/src/main/java/com/swmansion/rnscreens/ScreenWindowTraits.kt +1 -1
- package/android/src/main/java/com/swmansion/rnscreens/events/HeaderHeightChangeEvent.kt +3 -3
- package/android/src/main/res/base/anim/rns_ios_from_left_background_close.xml +5 -0
- package/android/src/main/res/base/anim/{rns_slide_out_to_left_ios.xml → rns_ios_from_left_background_open.xml} +1 -1
- package/android/src/main/res/base/anim/rns_ios_from_left_foreground_close.xml +6 -0
- package/android/src/main/res/base/anim/rns_ios_from_left_foreground_open.xml +6 -0
- package/android/src/main/res/base/anim/rns_ios_from_right_background_open.xml +5 -0
- package/android/src/paper/java/com/swmansion/rnscreens/FabricEnabledViewGroup.kt +1 -1
- package/common/cpp/react/renderer/components/rnscreens/RNSScreenComponentDescriptor.h +5 -99
- package/common/cpp/react/renderer/components/rnscreens/RNSScreenShadowNode.cpp +101 -0
- package/common/cpp/react/renderer/components/rnscreens/RNSScreenShadowNode.h +2 -0
- package/ios/RNSConvert.mm +4 -1
- package/ios/RNSFullWindowOverlay.mm +6 -0
- package/ios/RNSModalScreen.mm +7 -0
- package/ios/RNSScreen.mm +9 -0
- package/ios/RNSScreenContainer.mm +6 -0
- package/ios/RNSScreenContentWrapper.mm +6 -0
- package/ios/RNSScreenFooter.mm +6 -0
- package/ios/RNSScreenNavigationContainer.mm +7 -0
- package/ios/RNSScreenStack.mm +7 -7
- package/ios/RNSScreenStackHeaderConfig.mm +10 -0
- package/ios/RNSScreenStackHeaderSubview.mm +6 -3
- package/ios/RNSSearchBar.mm +7 -0
- package/lib/commonjs/TransitionProgressContext.js +1 -0
- package/lib/commonjs/TransitionProgressContext.js.map +1 -1
- package/lib/commonjs/components/Screen.js +58 -3
- package/lib/commonjs/components/Screen.js.map +1 -1
- package/lib/commonjs/components/Screen.web.js +2 -0
- package/lib/commonjs/components/Screen.web.js.map +1 -1
- package/lib/commonjs/components/ScreenContainer.js +1 -0
- package/lib/commonjs/components/ScreenContainer.js.map +1 -1
- package/lib/commonjs/components/ScreenStack.js +1 -0
- package/lib/commonjs/components/ScreenStack.js.map +1 -1
- package/lib/commonjs/components/ScreenStackHeaderConfig.js +1 -0
- package/lib/commonjs/components/ScreenStackHeaderConfig.js.map +1 -1
- package/lib/commonjs/components/SearchBar.js +1 -0
- package/lib/commonjs/components/SearchBar.js.map +1 -1
- package/lib/commonjs/core.js +1 -0
- package/lib/commonjs/core.js.map +1 -1
- package/lib/commonjs/fabric/FullWindowOverlayNativeComponent.js +1 -0
- package/lib/commonjs/fabric/FullWindowOverlayNativeComponent.js.map +1 -1
- package/lib/commonjs/fabric/ModalScreenNativeComponent.js +1 -0
- package/lib/commonjs/fabric/ModalScreenNativeComponent.js.map +1 -1
- package/lib/commonjs/fabric/NativeScreensModule.js +2 -1
- package/lib/commonjs/fabric/NativeScreensModule.js.map +1 -1
- package/lib/commonjs/fabric/ScreenContainerNativeComponent.js +1 -0
- package/lib/commonjs/fabric/ScreenContainerNativeComponent.js.map +1 -1
- package/lib/commonjs/fabric/ScreenNativeComponent.js +1 -0
- package/lib/commonjs/fabric/ScreenNativeComponent.js.map +1 -1
- package/lib/commonjs/fabric/ScreenNavigationContainerNativeComponent.js +1 -0
- package/lib/commonjs/fabric/ScreenNavigationContainerNativeComponent.js.map +1 -1
- package/lib/commonjs/fabric/ScreenStackHeaderConfigNativeComponent.js +1 -0
- package/lib/commonjs/fabric/ScreenStackHeaderConfigNativeComponent.js.map +1 -1
- package/lib/commonjs/fabric/ScreenStackHeaderSubviewNativeComponent.js +1 -0
- package/lib/commonjs/fabric/ScreenStackHeaderSubviewNativeComponent.js.map +1 -1
- package/lib/commonjs/fabric/ScreenStackNativeComponent.js +1 -0
- package/lib/commonjs/fabric/ScreenStackNativeComponent.js.map +1 -1
- package/lib/commonjs/fabric/SearchBarNativeComponent.js +2 -2
- package/lib/commonjs/fabric/SearchBarNativeComponent.js.map +1 -1
- package/lib/commonjs/native-stack/contexts/GHContext.js +1 -0
- package/lib/commonjs/native-stack/contexts/GHContext.js.map +1 -1
- package/lib/commonjs/native-stack/views/NativeStackView.js +4 -4
- package/lib/commonjs/native-stack/views/NativeStackView.js.map +1 -1
- package/lib/module/TransitionProgressContext.js +2 -0
- package/lib/module/TransitionProgressContext.js.map +1 -1
- package/lib/module/components/Screen.js +59 -3
- package/lib/module/components/Screen.js.map +1 -1
- package/lib/module/components/Screen.web.js +3 -0
- package/lib/module/components/Screen.web.js.map +1 -1
- package/lib/module/components/ScreenContainer.js +2 -0
- package/lib/module/components/ScreenContainer.js.map +1 -1
- package/lib/module/components/ScreenStack.js +2 -0
- package/lib/module/components/ScreenStack.js.map +1 -1
- package/lib/module/components/ScreenStackHeaderConfig.js +2 -0
- package/lib/module/components/ScreenStackHeaderConfig.js.map +1 -1
- package/lib/module/components/SearchBar.js +2 -0
- package/lib/module/components/SearchBar.js.map +1 -1
- package/lib/module/core.js +2 -0
- package/lib/module/core.js.map +1 -1
- package/lib/module/fabric/FullWindowOverlayNativeComponent.js +2 -0
- package/lib/module/fabric/FullWindowOverlayNativeComponent.js.map +1 -1
- package/lib/module/fabric/ModalScreenNativeComponent.js +2 -0
- package/lib/module/fabric/ModalScreenNativeComponent.js.map +1 -1
- package/lib/module/fabric/NativeScreensModule.js +2 -1
- package/lib/module/fabric/NativeScreensModule.js.map +1 -1
- package/lib/module/fabric/ScreenContainerNativeComponent.js +2 -0
- package/lib/module/fabric/ScreenContainerNativeComponent.js.map +1 -1
- package/lib/module/fabric/ScreenNativeComponent.js +2 -0
- package/lib/module/fabric/ScreenNativeComponent.js.map +1 -1
- package/lib/module/fabric/ScreenNavigationContainerNativeComponent.js +2 -0
- package/lib/module/fabric/ScreenNavigationContainerNativeComponent.js.map +1 -1
- package/lib/module/fabric/ScreenStackHeaderConfigNativeComponent.js +2 -0
- package/lib/module/fabric/ScreenStackHeaderConfigNativeComponent.js.map +1 -1
- package/lib/module/fabric/ScreenStackHeaderSubviewNativeComponent.js +2 -0
- package/lib/module/fabric/ScreenStackHeaderSubviewNativeComponent.js.map +1 -1
- package/lib/module/fabric/ScreenStackNativeComponent.js +2 -0
- package/lib/module/fabric/ScreenStackNativeComponent.js.map +1 -1
- package/lib/module/fabric/SearchBarNativeComponent.js +2 -0
- package/lib/module/fabric/SearchBarNativeComponent.js.map +1 -1
- package/lib/module/index.js +6 -6
- package/lib/module/native-stack/contexts/GHContext.js +2 -0
- package/lib/module/native-stack/contexts/GHContext.js.map +1 -1
- package/lib/module/native-stack/views/NativeStackView.js +4 -4
- package/lib/module/native-stack/views/NativeStackView.js.map +1 -1
- package/lib/typescript/TransitionProgressContext.d.ts.map +1 -1
- package/lib/typescript/components/Screen.d.ts.map +1 -1
- package/lib/typescript/components/Screen.web.d.ts.map +1 -1
- package/lib/typescript/components/ScreenContainer.d.ts.map +1 -1
- package/lib/typescript/components/ScreenStack.d.ts.map +1 -1
- package/lib/typescript/components/ScreenStackHeaderConfig.d.ts.map +1 -1
- package/lib/typescript/components/SearchBar.d.ts.map +1 -1
- package/lib/typescript/core.d.ts.map +1 -1
- package/lib/typescript/fabric/FullWindowOverlayNativeComponent.d.ts.map +1 -1
- package/lib/typescript/fabric/ModalScreenNativeComponent.d.ts.map +1 -1
- package/lib/typescript/fabric/NativeScreensModule.d.ts.map +1 -1
- package/lib/typescript/fabric/ScreenContainerNativeComponent.d.ts.map +1 -1
- package/lib/typescript/fabric/ScreenNativeComponent.d.ts +1 -1
- package/lib/typescript/fabric/ScreenNativeComponent.d.ts.map +1 -1
- package/lib/typescript/fabric/ScreenNavigationContainerNativeComponent.d.ts.map +1 -1
- package/lib/typescript/fabric/ScreenStackHeaderConfigNativeComponent.d.ts.map +1 -1
- package/lib/typescript/fabric/ScreenStackHeaderSubviewNativeComponent.d.ts.map +1 -1
- package/lib/typescript/fabric/ScreenStackNativeComponent.d.ts.map +1 -1
- package/lib/typescript/fabric/SearchBarNativeComponent.d.ts.map +1 -1
- package/lib/typescript/index.d.ts +18 -0
- package/lib/typescript/index.d.ts.map +1 -1
- package/lib/typescript/native-stack/contexts/GHContext.d.ts.map +1 -1
- package/lib/typescript/native-stack/types.d.ts +13 -3
- 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 +34 -6
- package/lib/typescript/types.d.ts.map +1 -1
- package/native-stack/README.md +28 -4
- package/package.json +1 -1
- package/src/TransitionProgressContext.tsx +2 -0
- package/src/components/Screen.tsx +71 -3
- package/src/components/Screen.web.tsx +3 -0
- package/src/components/ScreenContainer.tsx +2 -0
- package/src/components/ScreenStack.tsx +2 -0
- package/src/components/ScreenStackHeaderConfig.tsx +2 -0
- package/src/components/SearchBar.tsx +2 -0
- package/src/core.ts +2 -0
- package/src/fabric/FullWindowOverlayNativeComponent.ts +2 -0
- package/src/fabric/ModalScreenNativeComponent.ts +2 -0
- package/src/fabric/NativeScreensModule.ts +2 -0
- package/src/fabric/ScreenContainerNativeComponent.ts +2 -0
- package/src/fabric/ScreenNativeComponent.ts +5 -1
- package/src/fabric/ScreenNavigationContainerNativeComponent.ts +2 -0
- package/src/fabric/ScreenStackHeaderConfigNativeComponent.ts +2 -0
- package/src/fabric/ScreenStackHeaderSubviewNativeComponent.ts +2 -0
- package/src/fabric/ScreenStackNativeComponent.ts +2 -0
- package/src/fabric/SearchBarNativeComponent.ts +2 -0
- package/src/index.tsx +6 -6
- package/src/native-stack/contexts/GHContext.tsx +2 -0
- package/src/native-stack/types.tsx +13 -3
- package/src/native-stack/views/NativeStackView.tsx +8 -7
- package/src/types.tsx +42 -6
- package/windows/RNScreens/Screen.h +3 -1
- /package/android/src/main/res/base/anim/{rns_slide_in_from_left_ios.xml → rns_ios_from_right_background_close.xml} +0 -0
- /package/android/src/main/res/base/anim/{rns_slide_out_to_right_ios.xml → rns_ios_from_right_foreground_close.xml} +0 -0
- /package/android/src/main/res/base/anim/{rns_slide_in_from_right_ios.xml → rns_ios_from_right_foreground_open.xml} +0 -0
package/README.md
CHANGED
|
@@ -188,7 +188,7 @@ To take advantage of the native stack navigator primitive for React Navigation t
|
|
|
188
188
|
|
|
189
189
|
## `FullWindowOverlay`
|
|
190
190
|
|
|
191
|
-
Native `iOS` component for rendering views straight under the `Window`. Based on `RCTPerfMonitor`. You should treat it as a wrapper, providing full-screen, transparent view which receives no props and should ideally render one child `View`, being the root of its view hierarchy. For the example usage, see https://github.com/software-mansion/react-native-screens/blob/main/
|
|
191
|
+
Native `iOS` component for rendering views straight under the `Window`. Based on `RCTPerfMonitor`. You should treat it as a wrapper, providing full-screen, transparent view which receives no props and should ideally render one child `View`, being the root of its view hierarchy. For the example usage, see https://github.com/software-mansion/react-native-screens/blob/main/apps/src/tests/Test1096.tsx
|
|
192
192
|
|
|
193
193
|
## Interop with [react-native-navigation](https://github.com/wix/react-native-navigation)
|
|
194
194
|
|
package/android/build.gradle
CHANGED
|
@@ -9,7 +9,11 @@ buildscript {
|
|
|
9
9
|
rnsDefaultKotlinVersion = '1.8.0'
|
|
10
10
|
}
|
|
11
11
|
ext.safeExtGet = {prop, fallback ->
|
|
12
|
-
|
|
12
|
+
def props = (prop instanceof String) ? [prop] : prop
|
|
13
|
+
def result = props.find { key ->
|
|
14
|
+
return rootProject.ext.has(key)
|
|
15
|
+
}
|
|
16
|
+
return result ? rootProject.ext.get(result) : fallback
|
|
13
17
|
}
|
|
14
18
|
repositories {
|
|
15
19
|
google()
|
|
@@ -77,8 +81,8 @@ android {
|
|
|
77
81
|
}
|
|
78
82
|
|
|
79
83
|
defaultConfig {
|
|
80
|
-
minSdkVersion safeExtGet('minSdkVersion', rnsDefaultMinSdkVersion)
|
|
81
|
-
targetSdkVersion safeExtGet('targetSdkVersion', rnsDefaultTargetSdkVersion)
|
|
84
|
+
minSdkVersion safeExtGet(['minSdkVersion', 'minSdk'], rnsDefaultMinSdkVersion)
|
|
85
|
+
targetSdkVersion safeExtGet(['targetSdkVersion', 'targetSdk'], rnsDefaultTargetSdkVersion)
|
|
82
86
|
versionCode 1
|
|
83
87
|
versionName "1.0"
|
|
84
88
|
buildConfigField "boolean", "IS_NEW_ARCHITECTURE_ENABLED", IS_NEW_ARCHITECTURE_ENABLED.toString()
|
|
@@ -136,7 +140,7 @@ android {
|
|
|
136
140
|
}
|
|
137
141
|
}
|
|
138
142
|
res {
|
|
139
|
-
if (safeExtGet('compileSdkVersion', rnsDefaultCompileSdkVersion) >= 33) {
|
|
143
|
+
if (safeExtGet(['compileSdkVersion', 'compileSdk'], rnsDefaultCompileSdkVersion) >= 33) {
|
|
140
144
|
srcDirs = ["${androidResDir}/base", "${androidResDir}/v33"]
|
|
141
145
|
} else {
|
|
142
146
|
srcDirs = ["${androidResDir}/base"]
|
|
@@ -148,10 +152,26 @@ android {
|
|
|
148
152
|
repositories {
|
|
149
153
|
maven {
|
|
150
154
|
// All of React Native (JS, Obj-C sources, Android binaries) is installed from npm
|
|
151
|
-
|
|
155
|
+
|
|
156
|
+
// First look for the standard location of react-native, as in RN Hello World template
|
|
152
157
|
// https://github.com/facebook/react-native/blob/1e8f3b11027fe0a7514b4fc97d0798d3c64bc895/local-cli/templates/HelloWorld/android/build.gradle#L21
|
|
153
|
-
|
|
158
|
+
// TODO(kkafar): Note, that in latest template app https://github.com/react-native-community/template/blob/0f4745b7a9d84232aeedec2def8d75ab9b050d11/template/android/build.gradle
|
|
159
|
+
// this is not specified at all.
|
|
160
|
+
File standardRnAndroidDirLocation = file("$rootDir/../node_modules/react-native/android")
|
|
161
|
+
if (standardRnAndroidDirLocation.exists()) {
|
|
162
|
+
url standardRnAndroidDirLocation
|
|
163
|
+
} else {
|
|
164
|
+
// We're in non standard setup - try to use node resolver to locate the react-native package.
|
|
165
|
+
File reactNativePackage = file(["node", "--print", "require.resolve('react-native/package.json')"].execute(null, rootDir).text.trim())
|
|
166
|
+
def rnAndroidDirLocation = "$reactNativePackage.parentFile/android"
|
|
167
|
+
if (reactNativePackage.exists()) {
|
|
168
|
+
url rnAndroidDirLocation
|
|
169
|
+
} else {
|
|
170
|
+
println "[RNScreens] Failed to resolve react-native directory. Attempted locations: ${standardRnAndroidDirLocation}, ${rnAndroidDirLocation}"
|
|
171
|
+
}
|
|
172
|
+
}
|
|
154
173
|
}
|
|
174
|
+
|
|
155
175
|
mavenCentral()
|
|
156
176
|
mavenLocal()
|
|
157
177
|
google()
|
|
@@ -24,7 +24,7 @@ abstract class FabricEnabledViewGroup(
|
|
|
24
24
|
protected fun updateScreenSizeFabric(
|
|
25
25
|
width: Int,
|
|
26
26
|
height: Int,
|
|
27
|
-
headerHeight:
|
|
27
|
+
headerHeight: Int,
|
|
28
28
|
) {
|
|
29
29
|
updateState(width, height, headerHeight)
|
|
30
30
|
}
|
|
@@ -33,10 +33,11 @@ abstract class FabricEnabledViewGroup(
|
|
|
33
33
|
fun updateState(
|
|
34
34
|
width: Int,
|
|
35
35
|
height: Int,
|
|
36
|
-
headerHeight:
|
|
36
|
+
headerHeight: Int,
|
|
37
37
|
) {
|
|
38
38
|
val realWidth: Float = PixelUtil.toDIPFromPixel(width.toFloat())
|
|
39
39
|
val realHeight: Float = PixelUtil.toDIPFromPixel(height.toFloat())
|
|
40
|
+
val realHeaderHeight: Float = PixelUtil.toDIPFromPixel(headerHeight.toFloat())
|
|
40
41
|
|
|
41
42
|
// Check incoming state values. If they're already the correct value, return early to prevent
|
|
42
43
|
// infinite UpdateState/SetState loop.
|
|
@@ -54,7 +55,7 @@ abstract class FabricEnabledViewGroup(
|
|
|
54
55
|
putDouble("frameWidth", realWidth.toDouble())
|
|
55
56
|
putDouble("frameHeight", realHeight.toDouble())
|
|
56
57
|
putDouble("contentOffsetX", 0.0)
|
|
57
|
-
putDouble("contentOffsetY",
|
|
58
|
+
putDouble("contentOffsetY", realHeaderHeight.toDouble())
|
|
58
59
|
}
|
|
59
60
|
mStateWrapper?.updateState(map)
|
|
60
61
|
}
|
|
@@ -2,11 +2,50 @@ package com.swmansion.rnscreens
|
|
|
2
2
|
|
|
3
3
|
import android.annotation.SuppressLint
|
|
4
4
|
import android.content.Context
|
|
5
|
+
import android.os.Build
|
|
5
6
|
import androidx.appcompat.widget.Toolbar
|
|
7
|
+
import com.facebook.react.modules.core.ChoreographerCompat
|
|
8
|
+
import com.facebook.react.modules.core.ReactChoreographer
|
|
6
9
|
|
|
7
10
|
// This class is used to store config closer to search bar
|
|
8
11
|
@SuppressLint("ViewConstructor") // Only we construct this view, it is never inflated.
|
|
9
12
|
open class CustomToolbar(
|
|
10
13
|
context: Context,
|
|
11
14
|
val config: ScreenStackHeaderConfig,
|
|
12
|
-
) : Toolbar(context)
|
|
15
|
+
) : Toolbar(context) {
|
|
16
|
+
private var isLayoutEnqueued = false
|
|
17
|
+
private val layoutCallback: ChoreographerCompat.FrameCallback =
|
|
18
|
+
object : ChoreographerCompat.FrameCallback() {
|
|
19
|
+
override fun doFrame(frameTimeNanos: Long) {
|
|
20
|
+
isLayoutEnqueued = false
|
|
21
|
+
measure(
|
|
22
|
+
MeasureSpec.makeMeasureSpec(width, MeasureSpec.EXACTLY),
|
|
23
|
+
MeasureSpec.makeMeasureSpec(height, MeasureSpec.EXACTLY),
|
|
24
|
+
)
|
|
25
|
+
layout(left, top, right, bottom)
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
override fun requestLayout() {
|
|
30
|
+
super.requestLayout()
|
|
31
|
+
if (Build.VERSION.SDK_INT <= Build.VERSION_CODES.Q) {
|
|
32
|
+
// Below Android API 29, layout is not being requested when subviews are being added to the layout,
|
|
33
|
+
// leading to having their subviews in position 0,0 of the toolbar (as Android don't calculate
|
|
34
|
+
// the position of each subview, even if Yoga has correctly set their width and height).
|
|
35
|
+
// This is mostly the issue, when windowSoftInputMode is set to adjustPan in AndroidManifest.
|
|
36
|
+
// Thus, we're manually calling the layout **after** the current layout.
|
|
37
|
+
@Suppress("SENSELESS_COMPARISON") // mLayoutCallback can be null here since this method can be called in init
|
|
38
|
+
if (!isLayoutEnqueued && layoutCallback != null) {
|
|
39
|
+
isLayoutEnqueued = true
|
|
40
|
+
// we use NATIVE_ANIMATED_MODULE choreographer queue because it allows us to catch the current
|
|
41
|
+
// looper loop instead of enqueueing the update in the next loop causing a one frame delay.
|
|
42
|
+
ReactChoreographer
|
|
43
|
+
.getInstance()
|
|
44
|
+
.postFrameCallback(
|
|
45
|
+
ReactChoreographer.CallbackType.NATIVE_ANIMATED_MODULE,
|
|
46
|
+
layoutCallback,
|
|
47
|
+
)
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
}
|
|
@@ -5,20 +5,21 @@ import android.content.pm.ActivityInfo
|
|
|
5
5
|
import android.graphics.Paint
|
|
6
6
|
import android.os.Parcelable
|
|
7
7
|
import android.util.SparseArray
|
|
8
|
-
import android.util.TypedValue
|
|
9
8
|
import android.view.View
|
|
10
9
|
import android.view.ViewGroup
|
|
11
10
|
import android.view.WindowManager
|
|
12
11
|
import android.webkit.WebView
|
|
12
|
+
import android.widget.ImageView
|
|
13
13
|
import androidx.coordinatorlayout.widget.CoordinatorLayout
|
|
14
14
|
import androidx.core.view.children
|
|
15
15
|
import androidx.fragment.app.Fragment
|
|
16
|
+
import androidx.swiperefreshlayout.widget.SwipeRefreshLayout
|
|
16
17
|
import com.facebook.react.bridge.GuardedRunnable
|
|
17
18
|
import com.facebook.react.bridge.ReactContext
|
|
18
|
-
import com.facebook.react.uimanager.PixelUtil
|
|
19
19
|
import com.facebook.react.uimanager.UIManagerHelper
|
|
20
20
|
import com.facebook.react.uimanager.UIManagerModule
|
|
21
21
|
import com.facebook.react.uimanager.events.EventDispatcher
|
|
22
|
+
import com.facebook.react.views.scroll.ReactScrollView
|
|
22
23
|
import com.google.android.material.bottomsheet.BottomSheetBehavior
|
|
23
24
|
import com.swmansion.rnscreens.events.HeaderHeightChangeEvent
|
|
24
25
|
import com.swmansion.rnscreens.events.SheetDetentChangedEvent
|
|
@@ -140,17 +141,14 @@ class Screen(
|
|
|
140
141
|
val width = r - l
|
|
141
142
|
val height = b - t
|
|
142
143
|
|
|
143
|
-
val headerHeight = calculateHeaderHeight()
|
|
144
|
-
val totalHeight =
|
|
145
|
-
headerHeight.first + headerHeight.second // action bar height + status bar height
|
|
146
144
|
if (BuildConfig.IS_NEW_ARCHITECTURE_ENABLED) {
|
|
147
|
-
updateScreenSizeFabric(width, height,
|
|
145
|
+
updateScreenSizeFabric(width, height, t)
|
|
148
146
|
} else {
|
|
149
147
|
updateScreenSizePaper(width, height)
|
|
150
148
|
}
|
|
151
149
|
|
|
152
150
|
footer?.onParentLayout(changed, l, t, r, b, container!!.height)
|
|
153
|
-
notifyHeaderHeightChange(
|
|
151
|
+
notifyHeaderHeightChange(t)
|
|
154
152
|
}
|
|
155
153
|
}
|
|
156
154
|
|
|
@@ -367,7 +365,7 @@ class Screen(
|
|
|
367
365
|
parent?.let {
|
|
368
366
|
for (i in 0 until it.childCount) {
|
|
369
367
|
val child = it.getChildAt(i)
|
|
370
|
-
if (child
|
|
368
|
+
if (parent is SwipeRefreshLayout && child is ImageView) {
|
|
371
369
|
// SwipeRefreshLayout class which has CircleImageView as a child,
|
|
372
370
|
// does not handle `startViewTransition` properly.
|
|
373
371
|
// It has a custom `getChildDrawingOrder` method which returns
|
|
@@ -384,38 +382,22 @@ class Screen(
|
|
|
384
382
|
startTransitionRecursive(child.toolbar)
|
|
385
383
|
}
|
|
386
384
|
if (child is ViewGroup) {
|
|
385
|
+
// The children are miscounted when there's a FlatList with
|
|
386
|
+
// removeCLippedSubviews set to true (default).
|
|
387
|
+
// We add a simple view for each item in the list to make it work as expected.
|
|
388
|
+
// See https://github.com/software-mansion/react-native-screens/issues/2282
|
|
389
|
+
if (it is ReactScrollView && it.removeClippedSubviews) {
|
|
390
|
+
for (j in 0 until child.childCount) {
|
|
391
|
+
child.addView(View(context))
|
|
392
|
+
}
|
|
393
|
+
}
|
|
387
394
|
startTransitionRecursive(child)
|
|
388
395
|
}
|
|
389
396
|
}
|
|
390
397
|
}
|
|
391
398
|
}
|
|
392
399
|
|
|
393
|
-
private fun
|
|
394
|
-
val actionBarTv = TypedValue()
|
|
395
|
-
val resolvedActionBarSize =
|
|
396
|
-
context.theme.resolveAttribute(android.R.attr.actionBarSize, actionBarTv, true)
|
|
397
|
-
|
|
398
|
-
// Check if it's possible to get an attribute from theme context and assign a value from it.
|
|
399
|
-
// Otherwise, the default value will be returned.
|
|
400
|
-
val actionBarHeight =
|
|
401
|
-
TypedValue
|
|
402
|
-
.complexToDimensionPixelSize(actionBarTv.data, resources.displayMetrics)
|
|
403
|
-
.takeIf { resolvedActionBarSize && headerConfig?.isHeaderHidden != true && headerConfig?.isHeaderTranslucent != true }
|
|
404
|
-
?.let { PixelUtil.toDIPFromPixel(it.toFloat()).toDouble() } ?: 0.0
|
|
405
|
-
|
|
406
|
-
val statusBarHeight =
|
|
407
|
-
context.resources
|
|
408
|
-
.getIdentifier("status_bar_height", "dimen", "android")
|
|
409
|
-
// Count only status bar when action bar is visible and status bar is not hidden
|
|
410
|
-
.takeIf { it > 0 && isStatusBarHidden != true && actionBarHeight > 0 }
|
|
411
|
-
?.let { (context.resources::getDimensionPixelSize)(it) }
|
|
412
|
-
?.let { PixelUtil.toDIPFromPixel(it.toFloat()).toDouble() }
|
|
413
|
-
?: 0.0
|
|
414
|
-
|
|
415
|
-
return actionBarHeight to statusBarHeight
|
|
416
|
-
}
|
|
417
|
-
|
|
418
|
-
private fun notifyHeaderHeightChange(headerHeight: Double) {
|
|
400
|
+
private fun notifyHeaderHeightChange(headerHeight: Int) {
|
|
419
401
|
val screenContext = context as ReactContext
|
|
420
402
|
val surfaceId = UIManagerHelper.getSurfaceId(screenContext)
|
|
421
403
|
UIManagerHelper
|
|
@@ -454,6 +436,8 @@ class Screen(
|
|
|
454
436
|
SLIDE_FROM_LEFT,
|
|
455
437
|
FADE_FROM_BOTTOM,
|
|
456
438
|
IOS,
|
|
439
|
+
IOS_FROM_RIGHT,
|
|
440
|
+
IOS_FROM_LEFT,
|
|
457
441
|
}
|
|
458
442
|
|
|
459
443
|
enum class ReplaceAnimation {
|
|
@@ -182,7 +182,9 @@ class ScreenStack(
|
|
|
182
182
|
R.anim.rns_no_animation_medium,
|
|
183
183
|
)
|
|
184
184
|
StackAnimation.FADE_FROM_BOTTOM -> it.setCustomAnimations(R.anim.rns_fade_from_bottom, R.anim.rns_no_animation_350)
|
|
185
|
-
StackAnimation.IOS -> it.setCustomAnimations(R.anim.
|
|
185
|
+
StackAnimation.IOS -> it.setCustomAnimations(R.anim.rns_ios_from_right_foreground_open, R.anim.rns_ios_from_right_background_open)
|
|
186
|
+
StackAnimation.IOS_FROM_RIGHT -> it.setCustomAnimations(R.anim.rns_ios_from_right_foreground_open, R.anim.rns_ios_from_right_background_open)
|
|
187
|
+
StackAnimation.IOS_FROM_LEFT -> it.setCustomAnimations(R.anim.rns_ios_from_left_foreground_open, R.anim.rns_ios_from_left_background_open)
|
|
186
188
|
}
|
|
187
189
|
} else {
|
|
188
190
|
when (stackAnimation) {
|
|
@@ -220,7 +222,9 @@ class ScreenStack(
|
|
|
220
222
|
R.anim.rns_slide_out_to_bottom,
|
|
221
223
|
)
|
|
222
224
|
StackAnimation.FADE_FROM_BOTTOM -> it.setCustomAnimations(R.anim.rns_no_animation_250, R.anim.rns_fade_to_bottom)
|
|
223
|
-
StackAnimation.IOS -> it.setCustomAnimations(R.anim.
|
|
225
|
+
StackAnimation.IOS -> it.setCustomAnimations(R.anim.rns_ios_from_right_foreground_close, R.anim.rns_ios_from_right_background_close)
|
|
226
|
+
StackAnimation.IOS_FROM_RIGHT -> it.setCustomAnimations(R.anim.rns_ios_from_right_background_close, R.anim.rns_ios_from_right_foreground_close)
|
|
227
|
+
StackAnimation.IOS_FROM_LEFT -> it.setCustomAnimations(R.anim.rns_ios_from_left_background_close, R.anim.rns_ios_from_left_foreground_close)
|
|
224
228
|
}
|
|
225
229
|
}
|
|
226
230
|
}
|
|
@@ -413,6 +417,8 @@ class ScreenStack(
|
|
|
413
417
|
Build.VERSION.SDK_INT >= 33 ||
|
|
414
418
|
fragmentWrapper.screen.stackAnimation === StackAnimation.SLIDE_FROM_BOTTOM ||
|
|
415
419
|
fragmentWrapper.screen.stackAnimation === StackAnimation.FADE_FROM_BOTTOM ||
|
|
416
|
-
fragmentWrapper.screen.stackAnimation === StackAnimation.IOS
|
|
420
|
+
fragmentWrapper.screen.stackAnimation === StackAnimation.IOS ||
|
|
421
|
+
fragmentWrapper.screen.stackAnimation === StackAnimation.IOS_FROM_RIGHT ||
|
|
422
|
+
fragmentWrapper.screen.stackAnimation === StackAnimation.IOS_FROM_LEFT
|
|
417
423
|
}
|
|
418
424
|
}
|
|
@@ -87,7 +87,6 @@ open class ScreenViewManager :
|
|
|
87
87
|
stateWrapper: StateWrapper?,
|
|
88
88
|
): Any? {
|
|
89
89
|
if (BuildConfig.IS_NEW_ARCHITECTURE_ENABLED) {
|
|
90
|
-
// fabricViewStateManager should never be null in Fabric. The null check is only for Paper's empty impl.
|
|
91
90
|
view.setStateWrapper(stateWrapper)
|
|
92
91
|
}
|
|
93
92
|
return super.updateState(view, props, stateWrapper)
|
|
@@ -144,6 +143,8 @@ open class ScreenViewManager :
|
|
|
144
143
|
"slide_from_bottom" -> Screen.StackAnimation.SLIDE_FROM_BOTTOM
|
|
145
144
|
"fade_from_bottom" -> Screen.StackAnimation.FADE_FROM_BOTTOM
|
|
146
145
|
"ios" -> Screen.StackAnimation.IOS
|
|
146
|
+
"ios_from_right" -> Screen.StackAnimation.IOS_FROM_RIGHT
|
|
147
|
+
"ios_from_left" -> Screen.StackAnimation.IOS_FROM_LEFT
|
|
147
148
|
else -> throw JSApplicationIllegalArgumentException("Unknown animation type $animation")
|
|
148
149
|
}
|
|
149
150
|
}
|
|
@@ -225,7 +225,7 @@ object ScreenWindowTraits {
|
|
|
225
225
|
val window = activity.window
|
|
226
226
|
|
|
227
227
|
val screenForNavBarTranslucent = findScreenForTrait(screen, WindowTraits.NAVIGATION_BAR_TRANSLUCENT)
|
|
228
|
-
val translucent = screenForNavBarTranslucent?.isNavigationBarTranslucent ?:
|
|
228
|
+
val translucent = screenForNavBarTranslucent?.isNavigationBarTranslucent ?: return
|
|
229
229
|
|
|
230
230
|
// Following method controls whether to display edge-to-edge content that draws behind the navigation bar
|
|
231
231
|
WindowCompat.setDecorFitsSystemWindows(window, !translucent)
|
|
@@ -7,16 +7,16 @@ import com.facebook.react.uimanager.events.Event
|
|
|
7
7
|
class HeaderHeightChangeEvent(
|
|
8
8
|
surfaceId: Int,
|
|
9
9
|
viewId: Int,
|
|
10
|
-
private val headerHeight:
|
|
10
|
+
private val headerHeight: Int,
|
|
11
11
|
) : Event<HeaderHeightChangeEvent>(surfaceId, viewId) {
|
|
12
12
|
override fun getEventName() = EVENT_NAME
|
|
13
13
|
|
|
14
14
|
// As the same header height could appear twice, use header height as a coalescing key.
|
|
15
|
-
override fun getCoalescingKey(): Short = headerHeight.
|
|
15
|
+
override fun getCoalescingKey(): Short = headerHeight.toShort()
|
|
16
16
|
|
|
17
17
|
override fun getEventData(): WritableMap? =
|
|
18
18
|
Arguments.createMap().apply {
|
|
19
|
-
putDouble("headerHeight", headerHeight)
|
|
19
|
+
putDouble("headerHeight", headerHeight.toDouble())
|
|
20
20
|
}
|
|
21
21
|
|
|
22
22
|
companion object {
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
<?xml version="1.0" encoding="utf-8"?>
|
|
2
|
+
<translate xmlns:android="http://schemas.android.com/apk/res/android"
|
|
3
|
+
android:duration="@android:integer/config_shortAnimTime"
|
|
4
|
+
android:interpolator="@android:interpolator/accelerate_decelerate"
|
|
5
|
+
android:fromXDelta="0%"
|
|
6
|
+
android:toXDelta="-100%" />
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
<?xml version="1.0" encoding="utf-8"?>
|
|
2
|
+
<translate xmlns:android="http://schemas.android.com/apk/res/android"
|
|
3
|
+
android:duration="@android:integer/config_shortAnimTime"
|
|
4
|
+
android:interpolator="@android:interpolator/accelerate_decelerate"
|
|
5
|
+
android:fromXDelta="-100%"
|
|
6
|
+
android:toXDelta="0%" />
|
|
@@ -5,9 +5,9 @@
|
|
|
5
5
|
#endif
|
|
6
6
|
#include <react/debug/react_native_assert.h>
|
|
7
7
|
#include <react/renderer/components/rnscreens/Props.h>
|
|
8
|
+
#include <react/renderer/components/rnscreens/utils/RectUtil.h>
|
|
8
9
|
#include <react/renderer/core/ConcreteComponentDescriptor.h>
|
|
9
10
|
#include "RNSScreenShadowNode.h"
|
|
10
|
-
#include "utils/RectUtil.h"
|
|
11
11
|
|
|
12
12
|
namespace facebook {
|
|
13
13
|
namespace react {
|
|
@@ -19,9 +19,6 @@ class RNSScreenComponentDescriptor final
|
|
|
19
19
|
public:
|
|
20
20
|
using ConcreteComponentDescriptor::ConcreteComponentDescriptor;
|
|
21
21
|
|
|
22
|
-
static constexpr const char *kScreenDummyLayoutHelperClass =
|
|
23
|
-
"com/swmansion/rnscreens/utils/ScreenDummyLayoutHelper";
|
|
24
|
-
|
|
25
22
|
void adopt(ShadowNode &shadowNode) const override {
|
|
26
23
|
react_native_assert(dynamic_cast<RNSScreenShadowNode *>(&shadowNode));
|
|
27
24
|
auto &screenShadowNode = static_cast<RNSScreenShadowNode &>(shadowNode);
|
|
@@ -39,8 +36,8 @@ class RNSScreenComponentDescriptor final
|
|
|
39
36
|
#ifdef ANDROID
|
|
40
37
|
if (stateData.frameSize.width != 0 && stateData.frameSize.height != 0) {
|
|
41
38
|
// When we receive dimensions from JVM side we can remove padding used for
|
|
42
|
-
// correction, and we can stop applying height
|
|
43
|
-
//
|
|
39
|
+
// correction, and we can stop applying height and offset corrections for
|
|
40
|
+
// the frame.
|
|
44
41
|
// TODO: In future, when we have dynamic header height we might want to
|
|
45
42
|
// update Y offset correction here.
|
|
46
43
|
|
|
@@ -67,36 +64,11 @@ class RNSScreenComponentDescriptor final
|
|
|
67
64
|
screenShadowNode.setPadding({0, 0, 0, 0});
|
|
68
65
|
screenShadowNode.getFrameCorrectionModes().unset(
|
|
69
66
|
FrameCorrectionModes::Mode::FrameHeightCorrection);
|
|
67
|
+
screenShadowNode.getFrameCorrectionModes().unset(
|
|
68
|
+
FrameCorrectionModes::Mode::FrameOriginCorrection);
|
|
70
69
|
|
|
71
70
|
layoutableShadowNode.setSize(
|
|
72
71
|
Size{stateData.frameSize.width, stateData.frameSize.height});
|
|
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);
|
|
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
72
|
}
|
|
101
73
|
#else
|
|
102
74
|
if (stateData.frameSize.width != 0 && stateData.frameSize.height != 0) {
|
|
@@ -106,72 +78,6 @@ class RNSScreenComponentDescriptor final
|
|
|
106
78
|
#endif // ANDROID
|
|
107
79
|
ConcreteComponentDescriptor::adopt(shadowNode);
|
|
108
80
|
}
|
|
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
|
|
175
81
|
};
|
|
176
82
|
|
|
177
83
|
} // namespace react
|
|
@@ -15,6 +15,107 @@ Point RNSScreenShadowNode::getContentOriginOffset(
|
|
|
15
15
|
return {contentOffset.x, contentOffset.y};
|
|
16
16
|
}
|
|
17
17
|
|
|
18
|
+
std::optional<std::reference_wrapper<const ShadowNode::Shared>>
|
|
19
|
+
findHeaderConfigChild(const YogaLayoutableShadowNode &screenShadowNode) {
|
|
20
|
+
for (const ShadowNode::Shared &child : screenShadowNode.getChildren()) {
|
|
21
|
+
if (std::strcmp(child->getComponentName(), "RNSScreenStackHeaderConfig") ==
|
|
22
|
+
0) {
|
|
23
|
+
return {std::cref(child)};
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
return {};
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
static constexpr const char *kScreenDummyLayoutHelperClass =
|
|
30
|
+
"com/swmansion/rnscreens/utils/ScreenDummyLayoutHelper";
|
|
31
|
+
|
|
32
|
+
#ifdef ANDROID
|
|
33
|
+
std::optional<float> findHeaderHeight(
|
|
34
|
+
const int fontSize,
|
|
35
|
+
const bool isTitleEmpty) {
|
|
36
|
+
JNIEnv *env = facebook::jni::Environment::current();
|
|
37
|
+
|
|
38
|
+
if (env == nullptr) {
|
|
39
|
+
LOG(ERROR) << "[RNScreens] Failed to retrieve env\n";
|
|
40
|
+
return {};
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
jclass layoutHelperClass = env->FindClass(kScreenDummyLayoutHelperClass);
|
|
44
|
+
|
|
45
|
+
if (layoutHelperClass == nullptr) {
|
|
46
|
+
LOG(ERROR) << "[RNScreens] Failed to find class with id "
|
|
47
|
+
<< kScreenDummyLayoutHelperClass;
|
|
48
|
+
return {};
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
jmethodID computeDummyLayoutID =
|
|
52
|
+
env->GetMethodID(layoutHelperClass, "computeDummyLayout", "(IZ)F");
|
|
53
|
+
|
|
54
|
+
if (computeDummyLayoutID == nullptr) {
|
|
55
|
+
LOG(ERROR) << "[RNScreens] Failed to retrieve computeDummyLayout method ID";
|
|
56
|
+
return {};
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
jmethodID getInstanceMethodID = env->GetStaticMethodID(
|
|
60
|
+
layoutHelperClass,
|
|
61
|
+
"getInstance",
|
|
62
|
+
"()Lcom/swmansion/rnscreens/utils/ScreenDummyLayoutHelper;");
|
|
63
|
+
|
|
64
|
+
if (getInstanceMethodID == nullptr) {
|
|
65
|
+
LOG(ERROR) << "[RNScreens] Failed to retrieve getInstanceMethodID";
|
|
66
|
+
return {};
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
jobject packageInstance =
|
|
70
|
+
env->CallStaticObjectMethod(layoutHelperClass, getInstanceMethodID);
|
|
71
|
+
|
|
72
|
+
if (packageInstance == nullptr) {
|
|
73
|
+
LOG(ERROR)
|
|
74
|
+
<< "[RNScreens] Failed to retrieve packageInstance or the package instance was null on JVM side";
|
|
75
|
+
return {};
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
jfloat headerHeight = env->CallFloatMethod(
|
|
79
|
+
packageInstance, computeDummyLayoutID, fontSize, isTitleEmpty);
|
|
80
|
+
|
|
81
|
+
return {headerHeight};
|
|
82
|
+
}
|
|
83
|
+
#endif // ANDROID
|
|
84
|
+
|
|
85
|
+
void RNSScreenShadowNode::appendChild(const ShadowNode::Shared &child) {
|
|
86
|
+
YogaLayoutableShadowNode::appendChild(child);
|
|
87
|
+
#ifdef ANDROID
|
|
88
|
+
const auto &stateData = getStateData();
|
|
89
|
+
if (stateData.frameSize.width == 0 || stateData.frameSize.height == 0) {
|
|
90
|
+
// This code path should be executed only on the very first (few)
|
|
91
|
+
// layout(s), when we haven't received state update from JVM side yet.
|
|
92
|
+
auto headerConfigChildOpt = findHeaderConfigChild(*this);
|
|
93
|
+
auto &screenShadowNode = static_cast<RNSScreenShadowNode &>(*this);
|
|
94
|
+
|
|
95
|
+
// During creation of the shadow node children are not attached yet.
|
|
96
|
+
// We also do not want to set any padding in case.
|
|
97
|
+
if (headerConfigChildOpt) {
|
|
98
|
+
const auto &headerConfigChild = headerConfigChildOpt->get();
|
|
99
|
+
const auto &headerProps =
|
|
100
|
+
*std::static_pointer_cast<const RNSScreenStackHeaderConfigProps>(
|
|
101
|
+
headerConfigChild->getProps());
|
|
102
|
+
|
|
103
|
+
const auto headerHeight = headerProps.hidden
|
|
104
|
+
? 0.f
|
|
105
|
+
: findHeaderHeight(
|
|
106
|
+
headerProps.titleFontSize, headerProps.title.empty())
|
|
107
|
+
.value_or(0.f);
|
|
108
|
+
|
|
109
|
+
screenShadowNode.setPadding({0, 0, 0, headerHeight});
|
|
110
|
+
screenShadowNode.setHeaderHeight(headerHeight);
|
|
111
|
+
screenShadowNode.getFrameCorrectionModes().set(FrameCorrectionModes::Mode(
|
|
112
|
+
FrameCorrectionModes::Mode::FrameHeightCorrection |
|
|
113
|
+
FrameCorrectionModes::Mode::FrameOriginCorrection));
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
#endif // ANDROID
|
|
117
|
+
}
|
|
118
|
+
|
|
18
119
|
void RNSScreenShadowNode::layout(facebook::react::LayoutContext layoutContext) {
|
|
19
120
|
YogaLayoutableShadowNode::layout(layoutContext);
|
|
20
121
|
|
|
@@ -28,6 +28,8 @@ class JSI_EXPORT RNSScreenShadowNode final : public ConcreteViewShadowNode<
|
|
|
28
28
|
|
|
29
29
|
Point getContentOriginOffset(bool includeTransform) const override;
|
|
30
30
|
|
|
31
|
+
void appendChild(const ShadowNode::Shared &child) override;
|
|
32
|
+
|
|
31
33
|
void layout(LayoutContext layoutContext) override;
|
|
32
34
|
|
|
33
35
|
#pragma mark - Custom interface
|