react-navigation自定义导航栏(React Native)

1,168 阅读1分钟

使用 React Navigation 库

堆栈导航器(NativeStackNavigator

  • 自定义顶部导航栏样式:

    组件:

    export const MyHeader = ({ title, leftButton, bottomButton, rightButton, style }) => (
      <View style={[styles.header, style]}>
        <View style={{ flexDirection: "row", alignItems: 'center' }}>
          <View style={styles.leftButton}>{leftButton}</View>
          <Text style={[styles.headerTitle,rightButton?{left:50}:{textAlign: 'center'}]}>{title}</Text>
          {rightButton && <View style={styles.rightButton}>{rightButton}</View>}
        </View>
        {bottomButton && <View style={styles.bottomButton}>{bottomButton}</View>}
      </View>
    );
    
    export const header = ({ navigation, route, options, back }) => {
      const title = options.headerTitle() || route.name;
    
      return (
        <MyHeader
          title={title}
          leftButton={<TouchableOpacity onPress={() => {navigation.goBack()}} >
                        <Image style={styles.icon} source={require("../../../assets/back_light.png")} />
                      </TouchableOpacity>}
          bottomButton={options.headerRight && options.bottom ? options.headerRight():null}
          rightButton={options.headerRight && !options.bottom ? options.headerRight():null}
          style={options.headerStyle || {backgroundColor: 'rgba(118, 118, 118, 0.80)'}}
        />
      );
    };
    

    说明:

    需要添加的按钮在headerRight中声明,默认显示在右侧,设置bottom:true时显示在底部

    使用:

    const headerTitle = () => <Text style={styles.sectionTitle}>公钥</Text>;
      const headerRight = () => (
        <View style={styles.headerButtonContainer}>
          <TouchableOpacity activeOpacity={0.5} onPress={handleAdd} style={[styles.headerButton,{borderRightWidth: 1,}]}>
            <Image source={require("../../../../assets/addKey.png")} style={styles.headerIcon} />
          </TouchableOpacity>
          <TouchableOpacity activeOpacity={0.5} onPress={handleUpload} style={[styles.headerButton,{borderLeftWidth: 1,}]}>
            <Image source={require("../../../../assets/folder.png")} style={styles.headerIcon} />
          </TouchableOpacity>
        </View>
      );
    
      useLayoutEffect(() => {
        navigation.setOptions({ header,headerTitle,headerRight,headerTransparent:true, bottom:true });
      }, []);
    
    image.png
    const headerTitle = () => <Text style={styles.sectionTitle}>我的</Text>
      const headerRight = () => (
        <View style={styles.setContainer}>
          <TouchableOpacity activeOpacity={0.5} onPress={toggleSettingMenu}>
            <Image
              style={styles.icon}
              source={require("../../../../assets/set.png")}
            />
          </TouchableOpacity>
          <Modal
            transparent={true}
            visible={isSettingMenuVisible}
            onRequestClose={toggleSettingMenu}
          >
            <TouchableOpacity onPress={toggleSettingMenu} style={styles.overlay}>
              <View style={styles.modalContainer}>
                <TouchableOpacity onPress={()=>{handleEdit('EditPassword')}}><Text style={styles.modalText}>修改密码</Text></TouchableOpacity>
                <TouchableOpacity onPress={()=>{handleEdit('EditNickname')}}><Text style={styles.modalText}>修改昵称</Text></TouchableOpacity>
                <TouchableOpacity onPress={()=>{handleEdit('EditPhone')}}><Text style={styles.modalText}>修改手机</Text></TouchableOpacity>
                <TouchableOpacity onPress={()=>{handleEdit('ToggleEnterPrise')}}><Text style={styles.modalText}>切换企业</Text></TouchableOpacity>
                <TouchableOpacity onPress={handleLogout}><Text style={styles.modalText}>退出登录</Text></TouchableOpacity>
              </View>
            </TouchableOpacity>
          </Modal>
        </View>
      )
    
      useLayoutEffect(()=>{
        navigation.setOptions({headerTitle,headerRight, headerTransparent:true})
      },[isSettingMenuVisible])
    
    image.png

底部导航器(BottomTabNavigator

  • 自定义底部导航栏样式

    组件:

    function CustomTabBar({ state, descriptors, navigation }) {
    
      // 获取当前活动页面的路由描述符
      const route = state.routes[state.index];
      const descriptor = descriptors[route.key];
      const { options } = descriptor;
    
      // 从当前页面的选项中获取 tabBarVisible 属性,默认为 true
      const tabBarVisible = options.tabBarVisible !== false;
    
      return (
        <View style={[styles.tabBarContainer,{ display:tabBarVisible ? 'flex' : 'none' }]}>
          {state.routes.map((route, index) => {
            const { options } = descriptors[route.key];
            const isFocused = state.index === index;
    
            const onPress = () => {
              const event = navigation.emit({
                type: 'tabPress',
                target: route.key,
                canPreventDefault: true,
              });
    
              if (!isFocused && !event.defaultPrevented) {
                navigation.navigate(route.name);
              }
            };
    
            return (
              <TouchableOpacity
                key={route.key}
                onPress={onPress}
                style={[styles.tabBarButton, { backgroundColor: isFocused ? options.tabBarInactiveTintColor||'blue' : 'white'}]}
              >
                <Image style={styles.icon} source={tabBarIcons[route.name]}/>
              </TouchableOpacity>
            );
          })}
        </View>
      );
    }
    
    const tabBarIcons = {
      pageA: require('./assets/pageA.png'),
      pageB: require('./assets/pageB.png'),
      pageC: require('./assets/pageC.png'),
    }
    

    使用:

    <Tab.Navigator tabBar={props => <CustomTabBar {...props} />}
                   screenOptions={{headerShown: false}}>
    	<Tab.Screen name="ScreenA" component={ScreenA} options={{ tabBarLabelStyle: styles.tabBarLabel }}/>
      <Tab.Screen name="ScreenB" component={ScreenB} options={{ tabBarLabelStyle: styles.tabBarLabel }}/>
      <Tab.Screen name="ScreenC" component={ScreenC} options={{ tabBarLabelStyle: styles.tabBarLabel }}/>
    </Tab.Navigator>
    
    image.png