Skip to content

Commit 1cbdb33

Browse files
authored
fix(Android,Paper): header config blocks gestures close to the top of the screen (#2781)
## Description Fixes #2758 #2466 removed old workaround for header config blocking gestures - we just set top: `-100%` to place the headerconfig in the top of the screen effectively preventing blocking. #2466 removed these styles & frame correction is now applied directly in shadow node. This is done fine on Fabric, however the solution was not replicated on Paper. ## Changes Beside padding information we now send native toolbar height to header config shadow node on Paper. This information is used there to offset the header config position by this value. Should solve the problem. ### Screenshots | before | after | | - | - | | <img src="https://github.com/user-attachments/assets/640cad09-584d-4983-af92-11ae68d49f9f" alt="before" /> | <img src="https://github.com/user-attachments/assets/de15190e-e999-495f-8a6d-abf7f375d468" alt="after" /> | ## Test code and steps to reproduce `Example` -> `Header options` -> click on the very top button (very top of it). Previously the button was not effectively clicked. Now it works. ## Checklist - [ ] Included code example that can be used to test this change - [ ] Updated TS types - [ ] Updated documentation: <!-- For adding new props to native-stack --> - [ ] https://github.com/software-mansion/react-native-screens/blob/main/guides/GUIDE_FOR_LIBRARY_AUTHORS.md - [ ] https://github.com/software-mansion/react-native-screens/blob/main/native-stack/README.md - [ ] https://github.com/software-mansion/react-native-screens/blob/main/src/types.tsx - [ ] https://github.com/software-mansion/react-native-screens/blob/main/src/native-stack/types.tsx - [ ] Ensured that CI passes
1 parent 01472d1 commit 1cbdb33

File tree

5 files changed

+28
-23
lines changed

5 files changed

+28
-23
lines changed

android/src/fabric/java/com/swmansion/rnscreens/FabricEnabledHeaderConfigViewGroup.kt

Lines changed: 3 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -23,24 +23,19 @@ abstract class FabricEnabledHeaderConfigViewGroup(
2323
mStateWrapper = wrapper
2424
}
2525

26-
fun updatePaddings(
27-
paddingStart: Int,
28-
paddingEnd: Int,
29-
) {
30-
// Do nothing on Fabric. This method is used only on Paper.
31-
}
32-
3326
fun updateHeaderConfigState(
3427
width: Int,
3528
height: Int,
3629
paddingStart: Int,
3730
paddingEnd: Int,
3831
) {
32+
// Implementation of this method differs between Fabric & Paper!
3933
updateState(width, height, paddingStart, paddingEnd)
4034
}
4135

36+
// Implementation of this method differs between Fabric & Paper!
4237
@UiThread
43-
fun updateState(
38+
private fun updateState(
4439
width: Int,
4540
height: Int,
4641
paddingStart: Int,

android/src/main/java/com/swmansion/rnscreens/ScreenStackHeaderConfig.kt

Lines changed: 7 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -124,16 +124,13 @@ class ScreenStackHeaderConfig(
124124

125125
val contentInsetEnd = toolbar.currentContentInsetEnd + toolbar.paddingEnd
126126

127-
if (BuildConfig.IS_NEW_ARCHITECTURE_ENABLED) {
128-
updateHeaderConfigState(
129-
toolbar.width,
130-
toolbar.height,
131-
contentInsetStart,
132-
contentInsetEnd,
133-
)
134-
} else {
135-
updatePaddings(contentInsetStart, contentInsetEnd)
136-
}
127+
// Note that implementation of the callee differs between architectures.
128+
updateHeaderConfigState(
129+
toolbar.width,
130+
toolbar.height,
131+
contentInsetStart,
132+
contentInsetEnd,
133+
)
137134
}
138135

139136
override fun onLayout(

android/src/main/java/com/swmansion/rnscreens/ScreenStackHeaderConfigShadowNode.kt

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,14 +10,17 @@ internal class ScreenStackHeaderConfigShadowNode(
1010
) : LayoutShadowNode() {
1111
var paddingStart: Float = 0f
1212
var paddingEnd: Float = 0f
13+
var height: Float = 0f
1314

1415
override fun setLocalData(data: Any?) {
1516
if (data is PaddingBundle) {
1617
paddingStart = data.paddingStart
1718
paddingEnd = data.paddingEnd
19+
height = data.height
1820

1921
setPadding(Spacing.START, paddingStart)
2022
setPadding(Spacing.END, paddingEnd)
23+
setPosition(Spacing.TOP, -height)
2124
} else {
2225
super.setLocalData(data)
2326
}

android/src/main/java/com/swmansion/rnscreens/utils/PaddingBundle.kt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ package com.swmansion.rnscreens.utils
33
// Used only on Paper together with `setLocalData` mechanism to pass
44
// the information on header paddings to shadow node.
55
data class PaddingBundle(
6+
val height: Float,
67
val paddingStart: Float,
78
val paddingEnd: Float,
89
)

android/src/paper/java/com/swmansion/rnscreens/FabricEnabledHeaderConfigViewGroup.kt

Lines changed: 14 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ package com.swmansion.rnscreens
22

33
import android.content.Context
44
import android.view.ViewGroup
5+
import androidx.annotation.UiThread
56
import com.facebook.react.bridge.ReactContext
67
import com.facebook.react.uimanager.StateWrapper
78
import com.facebook.react.uimanager.UIManagerModule
@@ -13,32 +14,40 @@ abstract class FabricEnabledHeaderConfigViewGroup(
1314
) : ViewGroup(context) {
1415
private var lastPaddingStart = 0
1516
private var lastPaddingEnd = 0
17+
private var lastHeight = 0
1618

1719
fun setStateWrapper(wrapper: StateWrapper?) = Unit
1820

19-
// Do nothing on Paper. This method is used only on Fabric.
2021
fun updateHeaderConfigState(
2122
width: Int,
2223
height: Int,
2324
paddingStart: Int,
2425
paddingEnd: Int,
25-
) = Unit
26+
) {
27+
// Implementation of this method differs between Fabric & Paper!
28+
updateState(width, height, paddingStart, paddingEnd)
29+
}
2630

27-
fun updatePaddings(
31+
// Implementation of this method differs between Fabric & Paper!
32+
@UiThread
33+
private fun updateState(
34+
width: Int,
35+
height: Int,
2836
paddingStart: Int,
2937
paddingEnd: Int,
3038
) {
3139
// Note that on Paper we do not convert these props from px to dip. This is done internally by RN.
32-
if (abs(lastPaddingStart - paddingStart) < DELTA && abs(lastPaddingEnd - paddingEnd) < DELTA) {
40+
if (abs(lastPaddingStart - paddingStart) < DELTA && abs(lastPaddingEnd - paddingEnd) < DELTA && abs(lastHeight - height) < DELTA) {
3341
return
3442
}
3543

3644
lastPaddingStart = paddingStart
3745
lastPaddingEnd = paddingEnd
46+
lastHeight = height
3847

3948
val reactContext = context as? ReactContext
4049
val uiManagerModule = reactContext?.getNativeModule(UIManagerModule::class.java)
41-
uiManagerModule?.setViewLocalData(this.id, PaddingBundle(paddingStart.toFloat(), paddingEnd.toFloat()))
50+
uiManagerModule?.setViewLocalData(this.id, PaddingBundle(height.toFloat(), paddingStart.toFloat(), paddingEnd.toFloat()))
4251
}
4352

4453
companion object {

0 commit comments

Comments
 (0)