fix(mobile): avoid android modal header overlap (#4907)

This commit is contained in:
DIYgod 2026-03-11 11:43:41 +08:00 committed by GitHub
parent 7cc1cd549c
commit 65c18693da
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
5 changed files with 68 additions and 17 deletions

View File

@ -136,6 +136,7 @@ export default ({ config }: ConfigContext): ExpoConfig => {
],
require("./plugins/with-gradle-jvm-heap-size-increase.js"),
require("./plugins/with-android-jdk-21.js"),
require("./plugins/with-android-manifest-plugin.js"),
"expo-secure-store",
"@react-native-firebase/app",

View File

@ -0,0 +1,29 @@
const { withGradleProperties } = require("@expo/config-plugins")
function setGradleProperty(config, key, value) {
return withGradleProperties(config, (config) => {
const keyIndex = config.modResults.findIndex(
(item) => item.type === "property" && item.key === key,
)
const nextItem = {
type: "property",
key,
value,
}
if (keyIndex === -1) {
config.modResults.push(nextItem)
} else {
config.modResults.splice(keyIndex, 1, nextItem)
}
return config
})
}
module.exports = function withAndroidJdk21(config) {
let nextConfig = setGradleProperty(config, "react.internal.disableJavaVersionAlignment", "true")
nextConfig = setGradleProperty(nextConfig, "kotlin.jvm.target.validation.mode", "warning")
return nextConfig
}

View File

@ -33,14 +33,13 @@ import {
useCanDismiss,
useIsTopRouteInGroup,
useNavigation,
useScreenIsInModal,
useScreenIsInSheetModal,
} from "@/src/lib/navigation/hooks"
import { ScreenItemContext } from "@/src/lib/navigation/ScreenItemContext"
import { ThemedBlurView } from "../../common/ThemedBlurView"
import { PlatformActivityIndicator } from "../../ui/loading/PlatformActivityIndicator"
import { getDefaultHeaderHeight } from "../utils"
import { getNavigationHeaderLayout } from "../utils"
import { SetNavigationHeaderHeightContext } from "../views/NavigationHeaderContext"
import { FakeNativeHeaderTitle } from "./FakeNativeHeaderTitle"
@ -185,12 +184,12 @@ export const InternalNavigationHeader = ({
const frame = useSafeAreaFrame()
const sheetModal = useScreenIsInSheetModal()
const defaultHeight = useMemo(
const { headerHeight: defaultHeight, headerTopInset } = useMemo(
() =>
getDefaultHeaderHeight({
getNavigationHeaderLayout({
landscape: frame.width > frame.height,
modalPresentation: sheetModal,
topInset: sheetModal ? 0 : insets.top,
sheetModal,
topInset: insets.top,
}),
[frame, insets.top, sheetModal],
)
@ -229,11 +228,9 @@ export const InternalNavigationHeader = ({
hideableBottomHeight,
)
const isModal = useScreenIsInModal()
const rootTitleBarStyle = useAnimatedStyle(() => {
const styles = {
paddingTop: isModal ? 0 : insets.top,
paddingTop: headerTopInset,
position: "relative",
overflow: "hidden",
} satisfies DefaultStyle
@ -302,7 +299,7 @@ export const InternalNavigationHeader = ({
style={{
marginLeft: insets.left,
marginRight: insets.right,
height: !sheetModal ? defaultHeight - insets.top : defaultHeight,
height: defaultHeight - headerTopInset,
paddingHorizontal: titlebarPaddingHorizontal,
}}
pointerEvents={"box-none"}

View File

@ -41,3 +41,26 @@ export function getDefaultHeaderHeight({
return headerHeight + (modalPresentation ? 0 : topInset)
}
export function getNavigationHeaderLayout({
landscape,
sheetModal,
topInset,
}: {
landscape: boolean
sheetModal: boolean
topInset: number
}) {
const effectiveModalPresentation = isIOS && sheetModal
const headerTopInset = effectiveModalPresentation ? 0 : topInset
return {
headerTopInset,
effectiveModalPresentation,
headerHeight: getDefaultHeaderHeight({
landscape,
modalPresentation: effectiveModalPresentation,
topInset: headerTopInset,
}),
}
}

View File

@ -20,7 +20,7 @@ import { ReAnimatedScrollView } from "../../common/AnimatedComponents"
import type { InternalNavigationHeaderProps } from "../header/NavigationHeader"
import { InternalNavigationHeader } from "../header/NavigationHeader"
import { BottomTabBarBackgroundContext } from "../tabbar/contexts/BottomTabBarBackgroundContext"
import { getDefaultHeaderHeight } from "../utils"
import { getNavigationHeaderLayout } from "../utils"
import {
NavigationHeaderHeightContext,
SetNavigationHeaderHeightContext,
@ -64,12 +64,13 @@ export const SafeNavigationScrollView = ({
const frame = useSafeAreaFrame()
const sheetModal = useScreenIsInSheetModal()
const [headerHeight, setHeaderHeight] = useState(() =>
getDefaultHeaderHeight({
landscape: frame.width > frame.height,
modalPresentation: sheetModal,
topInset: insets.top,
}),
const [headerHeight, setHeaderHeight] = useState(
() =>
getNavigationHeaderLayout({
landscape: frame.width > frame.height,
sheetModal,
topInset: insets.top,
}).headerHeight,
)
const screenCtxValue = use(ScreenItemContext)