使用createStackNavigator和React Native实现透明的标题栏背景

48

我使用CRNA创建了一个项目,其中使用了React-Navigation。在其中一个屏幕上,我有一个覆盖整个屏幕的背景图像,并且我想要包含标题。

像这张图片一样:

enter image description here

我应该只隐藏标题并使用一个包含我想要的元素的视图吗?如果是,这会在深度链接的情况下引起问题吗?

解决方法

React Navigation提供了一个很酷的属性叫做headerTransparent,可以用来在标题下渲染一些内容。

所以代码看起来像这样:

static navigationOptions = {
    headerTransparent: true
  }

3
当我将headerTransparent设置为true时,我的标题栏中的返回按钮无法工作。您有任何解决方案吗? - MAhipal Singh
你能分享一下你的代码吗?记住是 headerTransparent : true 而不是 headerTransparent = true! - t97
谢谢,你的解决方案帮了我很大的忙。 - HardCoder
如果其他人无法使headerTransparent起作用:请确保您的代码中没有使用<SafeAreaView>,因为这会防止标题重叠到您的内容上 :) - Green
@MAhipalSingh 我也遇到了同样的问题,你有解决的办法吗? - undefined
11个回答

43

现在使用React Navigation 5,我们可以像这样做:

{
    headerShown: true,
    headerTransparent: true,
}
例如:
const Screen = ({ navigation }) => {
  navigation.setOptions({
    headerShown: true,
    headerTransparent: true,
  });

  return (
    <View>
      <Text>Render your component</Text>
    </View>
  );
};

4
你好,如何使透明的页眉在向下滚动时过渡为不透明? - kaizen
你到底把那个const放在哪里了?看起来非常不对! - showtime

13

这对我有用:

navigationOptions: {
  ...
  headerTransparent: true,
  headerStyle: {
      backgroundColor: 'transparent',
      ...
  }
}

9
为了实现这个效果,你需要按照以下步骤进行操作:
  1. 使用绝对定位、透明背景和无边框的样式更改导航头的样式。
  2. 使用 ImageBackground 组件作为屏幕的父组件,并使用你想要用作背景的图像。
  3. 添加 padding-top 到该 ImageBackground 上,以解决重叠问题。
因此,你的代码应该类似于这样:
import React, {Component} from 'react';
import {
  StyleSheet,
  Button,
  ImageBackground,
  Platform,
} from 'react-native';
import {
  createStackNavigator,
} from 'react-navigation';


class HomeScreen extends Component {
  render() {
    return (
        <ImageBackground
            style={styles.container}
            source={require('./images/bg.png')}
        >
          <Button
              onPress={() => {}}
              title="Just a button"
          />
        </ImageBackground>
    );
  }
}

const styles = StyleSheet.create({
  container: {
    flex: 1,
    paddingTop: Platform.OS === 'ios' ? 60 : 80,
  }
});

const App = createStackNavigator({
  Home: {
    screen: HomeScreen,
    navigationOptions: {
      title: 'Home',
      headerStyle: {
        position: 'absolute',
        backgroundColor: 'transparent',
        zIndex: 100,
        top: 0,
        left: 0,
        right: 0,
        elevation: 0,
        shadowOpacity: 0,
        borderBottomWidth: 0,
      }
    },
  }
})

export default App;

1
谢谢你的回答,它在某种程度上帮助我找到了解决方案。 - t97
1
你需要在与"headerStyle"同级别的位置添加"headerTransparent: true"。 - Andrew
@Naoufal,请更新答案,将navigationOptions中的headerTransparent: true包含在内。 - mxdi9i7
我将其与其他代码混合使用以达到所需的效果。 - Wylie

5

如果使用React Navigation 6.x,选项名称仍然是headerTransparent

             <Stack.Screen
                  name="BottomTab"
                  component={BottomTabNavigator}
                  options={{
                    headerTransparent: true,
                  }}
              />

4

解决方案:

navigationOptions: {
    headerTransparent: {
      position: 'absolute',
      backgroundColor: 'transparent',
      zIndex: 100,
      top: 0,
      left: 0,
      right: 0
    }

这是用于React Navigation v5的内容。 - JimmyWj4EHiM
2
在安卓手机上对我不起作用。(只能在iOS上运行) - Timur Ridjanovic

3

1
使用V5。
<NavigationContainer>
        <Stack.Navigator
            initialRouteName="Home"
            screenOptions={{
                headerShown: true,
                headerTransparent:true
            }}
        >
            <Stack.Screen name="Home" component={HomeScreen}/>
            <Stack.Screen name="Detail" component={DetailScreen}/>
            <Stack.Screen name="Setting" component={SettingScreen}/>
        </Stack.Navigator>
    </NavigationContainer>

1

我通过设置导航选项来实现了这个目标,如下所示:

BirdDetails.navigationOptions = () => {
  return {
    ...NavStyle,
    headerStyle: {
      backgroundColor: 'transparent',
    },
    headerTransparent: {
      position: 'absolute',
    },
    headerLeft: <Back></Back>,
    headerRight: <HeaderDetailsRight></HeaderDetailsRight>,
  };
};

0
这对我有用:
headerStyle: {elevation:0, backgroundColor:"transparent"}
将海拔高度设置为0,以便没有阴影。

0

我的做法就是这样,但它有一个缺陷,就是背景色必须硬编码。这种方法专门针对ScrollView,开始是透明的,变得不透明(保持原始文本)。

由于这是为了利用iOS的大型文本而设计的本地堆栈导航器,因此还需要调整headerHeight到适当的值。

  const navigation = useNavigation();
  return (
    <ScrollView
      onLayout={(e) => {
        navigation.setOptions({
          headerStyle: {
            backgroundColor: "transparent",
          },
        });
      }}
      onScroll={(e) => {
        const headerOpacity =
          Math.min(
            Math.max(e.nativeEvent.contentOffset.y, 0) / headerHeight,
            1.0
          ) ?? 0.0;
          navigation.setOptions({
            headerStyle: {
              elevation: headerOpacity,
              backgroundColor: `rgba(255,0,0,${headerOpacity})`,
            },
          });
      }}
      scrollEventThrottle={16}
      contentInsetAdjustmentBehavior="never"
    >

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接