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

React Native抽屉菜单添加子菜单实现方案咨询

嘿,我来帮你搞定这个抽屉菜单的展开子项需求!针对React Native 0.62和React Navigation的场景,我给你整理了清晰的实现思路和代码示例:

实现思路与步骤

1. 用状态管理控制展开/收起

首先你需要在自定义抽屉组件里引入useState钩子,用来维护Report菜单的展开状态——这样点击Report的时候就能切换显示/隐藏子菜单啦。

2. 改造Report项的交互逻辑

把原来直接导航的Report DrawerItem改成可点击切换状态的容器(比如TouchableOpacity),这样既能保留原有的图标和标签样式,又能实现展开/收起的交互,还可以加个箭头图标直观提示当前状态。

3. 条件渲染子菜单

根据状态值来决定是否渲染Old Report和New Report这两个子项,子项可以继续用DrawerItem保持样式统一,点击时导航到对应页面,还可以顺手收起子菜单优化体验。

修改后的完整代码示例
import React, { useState } from 'react';
import { View, Text, TouchableOpacity, StyleSheet } from 'react-native';
import { DrawerContentScrollView, DrawerItem, Drawer } from '@react-navigation/drawer';
import { Avatar } from 'react-native-paper';
import Icon from 'react-native-vector-icons/Ionicons';

// 这里保留你原有的样式和颜色定义
const Colors = { primary: '#your-primary-color' };
const styles = {
  drawerContent: { flex: 1 },
  userInfoSection: { padding: 16 },
  // 其他原有样式保持不变
};

const CustomDrawerContent = (props) => {
  // 新增状态:控制Report子菜单的展开/收起
  const [isReportExpanded, setIsReportExpanded] = useState(false);

  return (
    <View style={{flex:1}}>
      <DrawerContentScrollView {...props}>
        <View style={styles.drawerContent}>
          <View style={styles.userInfoSection}>
            <View style={{flexDirection:'row'}}>
              <Avatar.Image source={require('../Assets/user.png')} />
              <View style={{marginHorizontal:10, justifyContent:'center', width:'70%'}}>
                <Text style={{color:'gray'}}>k******@gmail.com</Text>
              </View>
            </View>
          </View>
          <View style={{alignItems:'center', marginVertical:15}}>
            <View style={{borderBottomColor:'gray',borderWidth:0.5, width:'90%'}} />
          </View>
          <View>
            <DrawerItem
              icon={({color, size}) => (
                <Icon name="md-home" size={size} color={Colors.primary} />
              )}
              label="Home"
              onPress={() => props.navigation.navigate('Home')}
            />
            {/* 改造Report项:点击切换展开状态 */}
            <TouchableOpacity
              style={{flexDirection: 'row', alignItems: 'center', paddingHorizontal: 16, paddingVertical: 12}}
              onPress={() => setIsReportExpanded(!isReportExpanded)}
            >
              <Icon name='ios-document' size={24} color={Colors.primary} />
              <Text style={{marginLeft: 16, fontSize: 16}}>Report</Text>
              {/* 展开/收起箭头图标 */}
              <Icon
                name={isReportExpanded ? 'ios-chevron-up' : 'ios-chevron-down'}
                size={20}
                color={Colors.primary}
                style={{marginLeft: 'auto'}}
              />
            </TouchableOpacity>
            {/* 根据状态渲染子菜单 */}
            {isReportExpanded && (
              <View style={{paddingLeft: 48}}>
                <DrawerItem
                  icon={({color, size}) => (
                    <Icon name='ios-document-outline' size={size} color={Colors.primary} />
                  )}
                  label='Old Report'
                  onPress={() => {
                    props.navigation.navigate('OldReport');
                    // 可选:点击子项后收起菜单
                    setIsReportExpanded(false);
                  }}
                />
                <DrawerItem
                  icon={({color, size}) => (
                    <Icon name='ios-document-add' size={size} color={Colors.primary} />
                  )}
                  label='New Report'
                  onPress={() => {
                    props.navigation.navigate('NewReport');
                    setIsReportExpanded(false);
                  }}
                />
              </View>
            )}
            <DrawerItem
              icon={({color, size}) => (
                <Icon name="ios-notifications" size={size} color={Colors.primary} />
              )}
              label='Notifications'
              onPress={() => props.navigation.navigate('Notification')}
            />
          </View>
        </View>
      </DrawerContentScrollView>
      <Drawer.Section>
        <DrawerItem
          icon={({color, size}) => (
            <Icon name="ios-exit" color="red" size={size} />
          )}
          label="SignOut"
          onPress={() => signOut()}
        />
      </Drawer.Section>
    </View>
  );
};

export default CustomDrawerContent;
关键注意点
  • 确保你的导航栈中已经注册了OldReport和NewReport这两个页面,否则导航会报错。
  • 子菜单的缩进样式可以根据你的UI需求调整paddingLeft的值。
  • 如果需要更复杂的动画效果,可以结合Animated API给子菜单添加展开/收起的过渡动画,不过对于基础需求来说上面的代码已经足够啦。

内容的提问来源于stack exchange,提问作者M.Kalidass

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.07 16:32:43