You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Expo Go Android端React Native视图被顶部导航栏遮挡问题排查

问题:Android端React Native应用视图被顶部导航栏遮挡(iOS正常)

近期在Expo Go中运行React Native应用时发现,Android端的视图会被顶部导航栏遮挡,此前无此问题;而iOS端视图可正常渲染在导航栏下方。以下为相关信息:

版本信息

"expo": "~47.0.11",
"react-native": "0.70.8",
"@react-navigation/bottom-tabs": "^6.5.7",
"@react-navigation/native": "^6.1.6",
"@react-navigation/native-stack": "^6.9.12",
"@react-navigation/stack": "^6.3.16",

相关代码

SearchStackScreen.jsx

const SearchStack = createNativeStackNavigator();

function SearchStackScreen() {
  Bugsnag.setContext('SearchStackScreen');

  const languageStore = useSelector(selectLanguageStore);
  const isDarkTheme = useTheme().dark;

  return (
    <SearchStack.Navigator
      screenOptions={{
        headerStyle: {
          backgroundColor: isDarkTheme ? colors.dark : colors.off_white
        }
      }}
    >
      <SearchStack.Screen
        name={TabBarStackScreenNames.search}
        component={SearchScreen}
        options={{
          headerLeft: () => <DefaultHeaderLeft />,
          headerShadowVisible: false,
          title: ''
        }}
      />
      <SearchStack.Screen
        name={MainStackScreenNames.search_profile}
        component={ProfileScreen}
        options={({ route }) => ({
          headerBackTitle: languageStore.back,
          headerRight: () => (
            <ProfileHeaderRight
              user={route.params.user}
              currentUser={route.params.currentUser}
              isCurrentUsersProfile={route.params.isCurrentUsersProfile}
            />
          ),
          title: route.params.title
        })}
      />
    </SearchStack.Navigator>
  );
}

SearchScreen.jsx

function SearchScreen({ navigation }) {
  const styles = StyleSheet.create({
    main: {
      flex: 1
    },
    no_users_text: {
      flex: 1,
      paddingVertical: sizes.sm,
      textAlign: 'center'
    },
    placeholder_container: {
      flex: 1,
      paddingHorizontal: sizes.md,
      paddingVertical: sizes.sm
    },
    results_container: {
      flex: 1
    },
    search_bar: {
      backgroundColor: isDarkTheme ? colors.dark : colors.off_white,
      borderRadius: 0
    },
    search_gif: {
      height: 200,
      marginBottom: -20
    }
  });

  return (
    <View style={globalStyles.main_screen_container}>
      {!currentUserInfo.verified ? (
        <CTAScreen
          body={languageStore.searching_disabled_message}
          buttonText={languageStore.get_verified}
          handleAction={() =>
            navigation.navigate(TabBarScreenNames.settings, {
              screen: MainStackScreenNames.settings_verify_identity_overview
            })
          }
          image={SearchGif}
          imageStyle={styles.search_gif}
          title={languageStore.searching_disabled_title}
        />
      ) : (
        <View style={styles.main}>
          <Searchbar
            iconColor={isDarkTheme && colors.white}
            inputStyle={globalStyles.text_regular}
            onChangeText={(text) => handleSearch(false, text)}
            onSubmitEditing={() => handleSearch(true, searchQuery)}
            placeholder={languageStore.search_for_villagers}
            placeholderTextColor={isDarkTheme ? colors.grey : colors.grey}
            selectionColor={colors.primary_light}
            style={styles.search_bar}
            value={searchQuery}
          />

          {loading ? (
            <View style={styles.placeholder_container}>
              <ListOfUsersPlaceholder twoLines={true} />
            </View>
          ) : (
            <View style={styles.results_container}>
              {noUsersFoundText ? (
                <Text
                  onPress={() => Keyboard.dismiss()}
                  style={[globalStyles.text_regular, styles.no_users_text]}
                  suppressHighlighting
                  variant="bodyLarge"
                >
                  {noUsersFoundText}
                </Text>
              ) : (
                <FlatList
                  data={usersToList}
                  keyExtractor={(_, index) => index}
                  renderItem={({ item, index }) => (
                    <UserListItem
                      displayLocation={true}
                      enlargePicture={true}
                      handlePictureAction={() =>
                        goToProfileScreen(
                          languageStore,
                          navigation,
                          item,
                          currentUserInfo,
                          true
                        )
                      }
                      index={index}
                      makeEverythingTouchable={true}
                      user={item}
                    />
                  )}
                  ItemSeparatorComponent={() => (
                    <View style={globalStyles.divider_thin} />
                  )}
                />
              )}
            </View>
          )}
        </View>
      )}
    </View>
  );
}

问题截图

Android视图被导航栏遮挡


解决方法

1. 全局配置导航安全区域适配

修改SearchStackScreen.jsx中的导航配置,添加contentInsetAdjustmentBehavior属性,让React Navigation自动适配安全区域:

<SearchStack.Navigator
  screenOptions={{
    headerStyle: {
      backgroundColor: isDarkTheme ? colors.dark : colors.off_white
    },
    // 自动适配Android安全区域,避免内容被导航栏遮挡
    contentInsetAdjustmentBehavior: 'automatic'
  }}
>

2. 给页面根视图添加安全区域内边距

在SearchScreen.jsx中引入react-native-safe-area-context的useSafeAreaInsets钩子,给根视图添加顶部内边距:

import { useSafeAreaInsets } from 'react-native-safe-area-context';

function SearchScreen({ navigation }) {
  const insets = useSafeAreaInsets();
  const styles = StyleSheet.create({
    main: {
      flex: 1,
      // 添加上部安全区域内边距,避开导航栏
      paddingTop: insets.top
    },
    // ...其余样式
  });

  // ...页面其余代码
}

3. 替换根视图为SafeAreaView

将SearchScreen中的外层View替换为SafeAreaView,自动让内容避开系统状态栏和导航栏:

import { SafeAreaView } from 'react-native';

// ...页面其余代码

return (
  <SafeAreaView style={globalStyles.main_screen_container}>
    {/* 原页面内容 */}
  </SafeAreaView>
);

4. 检查全局样式配置

确认globalStyles.main_screen_container是否包含安全区域适配,如果没有,修改该样式:

// globalStyles.js
import { useSafeAreaInsets } from 'react-native-safe-area-context';

const globalStyles = StyleSheet.create({
  main_screen_container: {
    flex: 1,
    paddingTop: useSafeAreaInsets().top
  }
});

内容的提问来源于stack exchange,提问作者Timothy C.

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.23 11:10:03