diff --git a/android/src/main/java/com/swmansion/rnscreens/Screen.kt b/android/src/main/java/com/swmansion/rnscreens/Screen.kt index fb4260fc3b..1ab8594ef3 100644 --- a/android/src/main/java/com/swmansion/rnscreens/Screen.kt +++ b/android/src/main/java/com/swmansion/rnscreens/Screen.kt @@ -127,6 +127,8 @@ class Screen( ) } + fun isTransparent(): Boolean = stackPresentation === StackPresentation.TRANSPARENT_MODAL + private fun hasWebView(viewGroup: ViewGroup): Boolean { for (i in 0 until viewGroup.childCount) { val child = viewGroup.getChildAt(i) diff --git a/android/src/main/java/com/swmansion/rnscreens/ScreenStack.kt b/android/src/main/java/com/swmansion/rnscreens/ScreenStack.kt index 4b520d14ac..afd6848978 100644 --- a/android/src/main/java/com/swmansion/rnscreens/ScreenStack.kt +++ b/android/src/main/java/com/swmansion/rnscreens/ScreenStack.kt @@ -97,14 +97,14 @@ class ScreenStack( var visibleBottom: ScreenFragmentWrapper? = null // this is only set if newTop has TRANSPARENT_MODAL presentation mode isDetachingCurrentScreen = false // we reset it so the previous value is not used by mistake for (i in screenWrappers.indices.reversed()) { - val screen = getScreenFragmentWrapperAt(i) - if (!dismissedWrappers.contains(screen)) { + val screenWrapper = getScreenFragmentWrapperAt(i) + if (!dismissedWrappers.contains(screenWrapper)) { if (newTop == null) { - newTop = screen + newTop = screenWrapper } else { - visibleBottom = screen + visibleBottom = screenWrapper } - if (!isTransparent(screen)) { + if (!screenWrapper.screen.isTransparent()) { break } } @@ -258,7 +258,7 @@ class ScreenStack( private fun turnOffA11yUnderTransparentScreen(visibleBottom: ScreenFragmentWrapper?) { if (screenWrappers.size > 1 && visibleBottom != null) { topScreenWrapper?.let { - if (isTransparent(it)) { + if (it.screen.isTransparent()) { val screenFragmentsBeneathTop = screenWrappers.slice(0 until screenWrappers.size - 1).asReversed() // go from the top of the stack excluding the top screen for (fragmentWrapper in screenFragmentsBeneathTop) { @@ -363,9 +363,6 @@ class ScreenStack( } companion object { - private fun isTransparent(fragmentWrapper: ScreenFragmentWrapper): Boolean = - fragmentWrapper.screen.stackPresentation === Screen.StackPresentation.TRANSPARENT_MODAL - private fun needsDrawReordering(fragmentWrapper: ScreenFragmentWrapper): Boolean = // On Android sdk 33 and above the animation is different and requires draw reordering. // For React Native 0.70 and lower versions, `Build.VERSION_CODES.TIRAMISU` is not defined yet. diff --git a/android/src/main/java/com/swmansion/rnscreens/ScreenStackFragment.kt b/android/src/main/java/com/swmansion/rnscreens/ScreenStackFragment.kt index dc7f6ba493..cca93143c9 100644 --- a/android/src/main/java/com/swmansion/rnscreens/ScreenStackFragment.kt +++ b/android/src/main/java/com/swmansion/rnscreens/ScreenStackFragment.kt @@ -154,7 +154,12 @@ class ScreenStackFragment : } override fun onPrepareOptionsMenu(menu: Menu) { - updateToolbarMenu(menu) + // If the screen is a transparent modal with hidden header we don't want to update the toolbar + // menu because it may erase the menu of the previous screen (which is still visible in these + // circumstances). See here: https://github.com/software-mansion/react-native-screens/issues/2271 + if (!screen.isTransparent() || screen.headerConfig?.isHeaderHidden == false) { + updateToolbarMenu(menu) + } return super.onPrepareOptionsMenu(menu) } diff --git a/apps/src/tests/Test2271.tsx b/apps/src/tests/Test2271.tsx new file mode 100644 index 0000000000..a858607545 --- /dev/null +++ b/apps/src/tests/Test2271.tsx @@ -0,0 +1,83 @@ +import { NavigationContainer } from '@react-navigation/native'; +import { + NativeStackScreenProps, + createNativeStackNavigator, +} from '@react-navigation/native-stack'; +import React from 'react'; +import { Button, StyleSheet, Text, View } from 'react-native'; +import { GestureHandlerRootView } from 'react-native-gesture-handler'; + +type StackParamList = { + Home: undefined; + Details: undefined; +}; + +const Stack = createNativeStackNavigator(); + +function HomeScreen({ + navigation, +}: NativeStackScreenProps) { + return ( + + Home Screen +