我试图隐藏在抽屉式导航器中按我的一条路线的功能,因为它是另一个导航器,也是应用程序中的默认位置。我希望将抽屉仅用于导航到不适合其他地方用户流的无关路线。在React Navigation 5之前,我只需设置drawerLabel: () => null
就可以实现这一点。但是,现在通过更改,我无法弄清楚如何以相同的方式隐藏它。
以下是我当前的导航代码:
const DrawerNavigator = () => {
const dispatch = useDispatch();
return (
<MainDrawerNavigator.Navigator
drawerContent={props => customDrawerContent(props, dispatch)}
drawerStyle={drawerStyle}
>
<MainDrawerNavigator.Screen
name="DrawerNav"
component={MainTabNavigator}
options={{
drawerLabel: () => null,
title: null,
drawerIcon: () => null
}}
/>
<MainDrawerNavigator.Screen
name="FAQNav"
component={FAQStackNavigator}
options={
{
drawerLabel: "FAQ",
drawerIcon: ({tintColor}) => <EvilIcons name={'question'} size={30} color={tintColor} />
}
}
/>
</MainDrawerNavigator.Navigator>
)
}
const customDrawerContent = (props, dispatch) => {
console.log(props.descriptors)
return (
<View style={{flex: 1}}>
<View style={{height: '90%'}}>
<DrawerContentScrollView {...props}>
<View style={styles.logoContainer}>
<Image
style={styles.image}
fadeDuration={0}
resizeMode={'contain'}
source={require('../assets/images/spikeball-logo-horizontal.png')}
/>
</View>
<TouchableOpacity style={styles.contactUsContainer} onPress={() => { Linking.openURL('https://spikeball.com/')}}>
<AntDesign style={styles.iconStyle} name={'shoppingcart'} size={25} color={'black'} />
<Text style={styles.drawerText}>Shop</Text>
</TouchableOpacity>
<TouchableOpacity style={styles.contactUsContainer} onPress={() => { Linking.openURL('https://support.spikeball.com/')}}>
<AntDesign style={styles.iconStyle} name={'contacts'} size={25} color={'black'} />
<Text style={styles.drawerText}>Contact Us</Text>
</TouchableOpacity>
<DrawerItemList
{...props}
/>
</DrawerContentScrollView>
</View>
<TouchableOpacity
style={styles.logoutContainer}
onPress={() => {
dispatch(authActions.logout());
}}>
<Text style={styles.logoutText}>SIGN OUT</Text>
</TouchableOpacity>
</View>
)
}
链接到显示不良输出的图像。基本上,我希望从焦点栏上隐藏蓝色焦点和整个导航项。 UNDESIRED Output
答案 0 :(得分:10)
最佳解决方案是先过滤道具,然后再将其传递到 DrawerItemList 。这仅适用于反应导航5
INTERACTION
}
答案 1 :(得分:6)
解决了以下问题
import React from 'react';
import { SafeAreaView, View, Text, StyleSheet, Image, Linking } from 'react-native';
import { EvilIcons, AntDesign } from '@expo/vector-icons';
import { useDispatch } from 'react-redux';
import { createDrawerNavigator, DrawerContentScrollView, DrawerItemList, DrawerItem } from '@react-navigation/drawer';
import MainTabNavigator from './MainTabNavigator';
import FAQStackNavigator from './FAQStackNavigator';
import { TouchableOpacity } from 'react-native-gesture-handler';
import * as authActions from '../store/actions/auth';
import { moderateScale } from '../utils/fontScale';
const MainDrawerNavigator = createDrawerNavigator();
const DrawerNavigator = () => {
const dispatch = useDispatch();
return (
<MainDrawerNavigator.Navigator
drawerContent={props => customDrawerContent(props, dispatch)}
drawerStyle={drawerStyle}
>
<MainDrawerNavigator.Screen
name="DrawerNav"
component={MainTabNavigator}
options={{
drawerLabel: () => null,
title: null,
drawerIcon: () => null
}}
/>
<MainDrawerNavigator.Screen
name="FAQNav"
component={FAQStackNavigator}
options={
{
drawerLabel: "FAQ",
drawerIcon: ({tintColor}) => <EvilIcons name={'question'} size={30} color={tintColor} />
}
}
/>
</MainDrawerNavigator.Navigator>
)
}
const customDrawerContent = (props, dispatch) => {
return (
<View style={{flex: 1}}>
<View style={{height: '90%'}}>
<DrawerContentScrollView {...props}>
<View style={styles.logoContainer}>
<Image
style={styles.image}
fadeDuration={0}
resizeMode={'contain'}
source={require('...')}
/>
</View>
<TouchableOpacity style={styles.contactUsContainer} onPress={() => { Linking.openURL('...')}}>
<AntDesign style={styles.iconStyle} name={'shoppingcart'} size={25} color={'black'} />
<Text style={styles.drawerText}>Shop</Text>
</TouchableOpacity>
<TouchableOpacity style={styles.contactUsContainer} onPress={() => { Linking.openURL('...')}}>
<AntDesign style={styles.iconStyle} name={'contacts'} size={25} color={'black'} />
<Text style={styles.drawerText}>Contact Us</Text>
</TouchableOpacity>
{/* Tried just disabling using DrawerItemList but wasn't working so made
complete custom drawer component and navigate properly using props.navigation.navigate */}
{/* <DrawerItemList
{...props}
/> */}
<TouchableOpacity
style={styles.contactUsContainer}
onPress={() => { console.log(props.navigation.navigate('FAQNav'))}}
>
<EvilIcons name={'question'} size={30} color={'black'} />
<Text style={styles.drawerText}>FAQ</Text>
</TouchableOpacity>
</DrawerContentScrollView>
</View>
<TouchableOpacity
style={styles.logoutContainer}
onPress={() => {
dispatch(authActions.logout());
}}>
<Text style={styles.logoutText}>SIGN OUT</Text>
</TouchableOpacity>
</View>
)
}
const drawerStyle = {
activeTintColor: 'black',
inactiveTintColor: 'black',
labelStyle: {
fontFamily: 'montserrat',
marginVertical: 16,
marginHorizontal: 0,
},
iconContainerStyle: {
justifyContent: 'center',
alignItems: 'center',
},
itemStyle: {
}
}
const styles = StyleSheet.create({
safeArea: {
flex: 1,
paddingTop: Platform.OS === 'android' ? 25 : 0
},
container: {
flex: 1,
},
logoContainer: {
width: '100%',
height: moderateScale(50),
alignItems: 'center',
justifyContent: 'center',
marginBottom: 5,
padding: 5,
},
image: {
resizeMode: 'contain',
width: '80%',
height: '100%',
},
contactUsContainer: {
flexDirection: 'row',
width: '100%',
height: 50,
alignItems: 'center',
paddingLeft: 15
},
logoutContainer: {
flexDirection: 'row',
width: '100%',
height: 50,
alignItems: 'flex-end',
justifyContent: 'center',
},
drawerText: {
fontFamily: 'montserrat',
marginLeft: 16,
},
logoutText: {
fontFamily: 'montserrat',
color: '#b23b3b'
}
});
export default DrawerNavigator;
答案 2 :(得分:0)
对我来说,您最好创建https://reactnavigation.org/docs/nesting-navigators/#navigator-specific-methods-are-available-in-the-navigators-nested-inside中记录的带有堆栈和抽屉屏幕的嵌套导航器,而不是隐藏抽屉项目。
答案 3 :(得分:0)
React导航解决方案5
我最终使用了以下代码-
drawerContent={props => customDrawerContent(props, dispatch)}
customDrawerContent的代码-
{state.routes.map((route, i) => {
if(route.name === 'App') return;
const focused = i === state.index;
const { title, drawerLabel, drawerIcon } = descriptors[route.key].options;
return (
<DrawerItem
key={route.key}
label={
drawerLabel !== undefined
? drawerLabel
: title !== undefined
? title
: route.name
}
icon={drawerIcon}
focused={focused}
activeTintColor={activeTintColor}
inactiveTintColor={inactiveTintColor}
activeBackgroundColor={activeBackgroundColor}
inactiveBackgroundColor={inactiveBackgroundColor}
labelStyle={labelStyle}
style={itemStyle}
to={buildLink(route.name, route.params)}
onPress={() => {
navigation.dispatch({
...(focused
? DrawerActions.closeDrawer()
: CommonActions.navigate(route.name)),
target: state.key,
});
}}
/>
);
})}
完整的代码可以在这里找到-
https://gist.github.com/yashkumarsharma/a56f4fe1517ee8ce07c153d2d2795f6f
答案 4 :(得分:0)
@Lenin Sheikh 解决方案有效,但正如评论中强调的那样,它引入了另一个问题,即无法单击抽屉菜单中的某些组件。我通过使用两个步骤解决了这个问题(显然是在应用 @Lenin Sheikh 解决方案之后)。
将隐藏的项目移到列表底部
选择一个默认组件,特别是如果它是隐藏组件之一
<Drawer.Navigator
initialRouteName='Home'// Specify the default component
drawerContent={
(props) => (
<DrawerList {...props} />)
}>
<Drawer.Screen name="Component 1"
component={Component1}
options={{ title: "Component one", headerShown:
false }} />
<Drawer.Screen name="Component 2"
component={Component2}
options={{ title: "Component 2", headerShown: false
}} />
<Drawer.Screen name="Logout"
component={LogoutPage}
options={{ title: "Logout", headerShown: true }} />
<Drawer.Screen name="Home" component={HomePage}
options={{
title: "",
headerShown: false,
}} />//This is the hidden component
</Drawer.Navigator>
答案 5 :(得分:0)
我刚刚找到了解决类似问题的方法。长话短说,我使用 Stack、Tabs 和 Drawer(用于汉堡菜单)。我设法组合了所有导航,但抽屉显示了我不想要的主页按钮。
我找到的解决方案在这里:
我也遇到了问题,即第一个抽屉菜单选项突出显示且不可点击。为此,我只需要将隐藏的菜单屏幕移动到抽屉导航的底部。 :) 我知道这不是最漂亮的解决方案,但我想我明白了。我希望它会帮助某人。这是我的代码:
function DrawerNavigator() {
return (
<NavigationContainer>
<Drawer.Navigator
initialRouteName="Home"
drawerContent={props => {
const filteredProps = {
...props,
state: {
...props.state,
routeNames: props.state.routeNames.filter(routeName => {
routeName !== 'Home';
}),
routes: props.state.routes.filter(route => route.name !== 'Home'),
},
};
return (
<DrawerContentScrollView {...filteredProps}>
<DrawerItemList {...filteredProps} />
</DrawerContentScrollView>
);
}}>
<Drawer.Screen name="Notifications" component={ProfileScreen} />
<Drawer.Screen name="Notifications2" component={ProfileScreen} />
<Drawer.Screen name="Home" component={StackNavigator} />
</Drawer.Navigator>
</NavigationContainer>
);
}
附言所有屏幕都是假的,所以忽略它没有意义:)
当我睡个好觉并重构它时,我可以并且会分享我的整个导航,但不要犹豫,询问您是否需要更多代码。干杯!
答案 6 :(得分:0)
在我踏上 Github 上的 How to hide DrawerView.Item in DrawerNavigator contentComponent #795 之前,上述解决方案均不适合我。
其他人的评论使我能够为 react-native v5 提出一个动态且有效的解决方案。
const CustomDrawer = props => {
const {state, descriptors, navigation} = props;
const buildLink = useLinkBuilder();
return (
<DrawerContentScrollView {...props}>
{state.routes.map((route, i) => {
const isHidden = descriptors[route.key].options?.hidden; // <--- Added this line
if (isHidden === true) return null; // <--- Added this line
const focused = i === state.index;
const {
title,
drawerLabel,
drawerIcon,
drawerActiveTintColor,
drawerInactiveTintColor,
drawerActiveBackgroundColor,
drawerInactiveBackgroundColor,
drawerLabelStyle,
drawerItemStyle,
} = descriptors[route.key].options;
return (
<DrawerItem
key={route.key}
label={
drawerLabel !== undefined
? drawerLabel
: title !== undefined
? title
: route.name
}
icon={drawerIcon}
focused={focused}
activeTintColor={drawerActiveTintColor}
inactiveTintColor={drawerInactiveTintColor}
activeBackgroundColor={drawerActiveBackgroundColor}
inactiveBackgroundColor={drawerInactiveBackgroundColor}
labelStyle={drawerLabelStyle}
style={drawerItemStyle}
to={buildLink(route.name, route.params)}
onPress={() => {
navigation.dispatch({
...(focused
? DrawerActions.closeDrawer()
: CommonActions.navigate(route.name)),
target: state.key,
});
}}
/>
);
})}
</DrawerContentScrollView>
);
};
export default CustomDrawer;
然后你所要做的就是在 Drawer.Navigator 中使用 CustomDrawer 并将隐藏选项传递给 Drawer.Screen,如下所示:
<Drawer.Navigator
initialRouteName={ROUTES.SIGN_IN}
drawerPosition="right"
drawerContent={props => <CustomDrawer {...props} />}>
<Drawer.Screen
name={ROUTES.SIGN_IN}
component={SignInContainer}
options={{headerShown: false, hidden: true}}
/>
<Drawer.Screen
name={ROUTES.DASHBOARD}
component={withHeader(DashboardContainer)}
options={{headerLeft: false}}
/>
</Drawer.Navigator>