React Navigation 5 隐藏抽屉项目
React Navigation 5 Hide Drawer Item
我试图隐藏在抽屉导航器中按我的路线之一的功能,因为它是另一个导航器和应用程序中的默认位置。我希望抽屉仅用于导航到不适合其他地方用户流的无关路线。在 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>
)
}
Link 显示不需要的输出的图像。基本上我希望蓝色焦点和整个导航项目专门隐藏在导航栏中。
UNDESIRED Output
解决了以下问题
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;
对我来说,您最好创建一个带有堆栈和抽屉屏幕的嵌套导航器,如 https://reactnavigation.org/docs/nesting-navigators/#navigator-specific-methods-are-available-in-the-navigators-nested-inside 中所述,而不是隐藏抽屉项目。
最好的解决方案是在将 props 传递给 DrawerItemList 之前对其进行过滤。这仅适用于反应导航 5
//custom drawer content
export default props => {
const { state, ...rest } = props;
const newState = { ...state} //copy from state before applying any filter. do not change original state
newState.routes = newState.routes.filter(item => item.name !== 'Login') //replace "Login' with your route name
return (
<DrawerContentScrollView {...props}>
<DrawerItemList state={newState} {...rest} />
</DrawerContentScrollView>
)
}
React Navigation 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
@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>
我刚刚找到了解决我的类似问题的方法。长话短说,我使用 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>
);
}
p.s。所有屏幕都是假的,所以忽略它没有意义:)
当我睡个好觉并重构它时,我可以并且会分享我的整个导航,但如果您需要更多代码,请随时询问。干杯!
None 以上解决方案对我有用,直到我在 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>
查看 React Navigation 源代码后,我认为最好的选择是向要隐藏的抽屉屏幕添加一个 drawerItemStyle 选项。只需将高度设置为 0.
例如
<Drawer.Screen
name="Home"
component={MainStackScreen}
options={{
drawerItemStyle: { height: 0 }
}}
/>
它似乎工作得很好。
我正在使用 React Navigation 6,但这可能也适用于 v5。
这很好用
<Drawer.Screen name="Home" component={MainStackScreen}
options={{
drawerItemStyle: { display: 'none' }
}}
/>
我试图隐藏在抽屉导航器中按我的路线之一的功能,因为它是另一个导航器和应用程序中的默认位置。我希望抽屉仅用于导航到不适合其他地方用户流的无关路线。在 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>
)
}
Link 显示不需要的输出的图像。基本上我希望蓝色焦点和整个导航项目专门隐藏在导航栏中。 UNDESIRED Output
解决了以下问题
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;
对我来说,您最好创建一个带有堆栈和抽屉屏幕的嵌套导航器,如 https://reactnavigation.org/docs/nesting-navigators/#navigator-specific-methods-are-available-in-the-navigators-nested-inside 中所述,而不是隐藏抽屉项目。
最好的解决方案是在将 props 传递给 DrawerItemList 之前对其进行过滤。这仅适用于反应导航 5
//custom drawer content
export default props => {
const { state, ...rest } = props;
const newState = { ...state} //copy from state before applying any filter. do not change original state
newState.routes = newState.routes.filter(item => item.name !== 'Login') //replace "Login' with your route name
return (
<DrawerContentScrollView {...props}>
<DrawerItemList state={newState} {...rest} />
</DrawerContentScrollView>
)
}
React Navigation 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
@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>
我刚刚找到了解决我的类似问题的方法。长话短说,我使用 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>
);
}
p.s。所有屏幕都是假的,所以忽略它没有意义:)
当我睡个好觉并重构它时,我可以并且会分享我的整个导航,但如果您需要更多代码,请随时询问。干杯!
None 以上解决方案对我有用,直到我在 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>
查看 React Navigation 源代码后,我认为最好的选择是向要隐藏的抽屉屏幕添加一个 drawerItemStyle 选项。只需将高度设置为 0.
例如
<Drawer.Screen
name="Home"
component={MainStackScreen}
options={{
drawerItemStyle: { height: 0 }
}}
/>
它似乎工作得很好。
我正在使用 React Navigation 6,但这可能也适用于 v5。
这很好用
<Drawer.Screen name="Home" component={MainStackScreen}
options={{
drawerItemStyle: { display: 'none' }
}}
/>