我有一个应用程序,它需要能够使用两个抽屉式导航器,一个在标题的左侧和右侧。
我现在可以用滑动手势打开两个抽屉,但是我需要能够以编程方式打开它。我发现navigation.openDrawer()
函数仅适用于其中一个抽屉,而不适用于另一个,因为它只能使用我的抽屉导航器中的一个导航道具(以先到者为准)。
以下是我的渲染功能:
const LeftStack = createStackNavigator(
{
LeftDrawerStack
},
{
navigationOptions: ({navigation}) => ({
headerLeft: (
<TouchableOpacity onPress={() => navigation.openDrawer()}>
<Icon style={{marginLeft: 10}} name='menu'/>
</TouchableOpacity>
)
})
}
);
const RightStack = createStackNavigator(
{
RightDrawerStack
},
{
navigationOptions: ({navigation}) => ({
headerRight: (
<TouchableOpacity onPress={() => navigation.openDrawer()}>
<Icon style={{marginRight: 10}} name='ios-bulb'/>
</TouchableOpacity>
)
})
}
);
export const RouteStack = createStackNavigator(
{
screen: LoginScreen,
navigationOptions: ({navigation}) => ({
header: null
}),
LeftStack,
RightStack
}
);
这是我的抽屉路线:
export const LeftDrawerStack = createDrawerNavigator(
{
Dashboard: {
screen: DashboardScreen
},
History: {
screen: HistoryScreen
},
Privacy: {
screen: PrivacyPolicyScreen
},
TermsAndConditions: {
screen: TermsAndConditionsScreen
}
}, {
initialRouteName: 'Dashboard',
contentComponent: LeftDrawerScreen
}
);
export const RightDrawerStack = createDrawerNavigator(
{
LeftDrawerStack,
Settings: {
screen: SettingsScreen
}
}, {
drawerPosition: 'right',
contentComponent: RightDrawerScreen
}
);
这是到目前为止我的导航外观的图片,但是两个汉堡菜单都在右侧打开相同的菜单,而不是在各自侧面打开一个菜单。
我可能会缺少某些部分,但是如果我忘记了任何信息,我一定会发布更多信息!
答案 0 :(得分:1)
我能够通过以下设置来做到这一点(尝试像这样对您的结构进行更改):
const LeftDrawer = createDrawerNavigator(
{
LeftDrawer: MyStackNavigator,
},
{
getCustomActionCreators: (route, stateKey) => { return { toggleLeftDrawer: () => DrawerActions.toggleDrawer({ key: stateKey }) }; },
drawerPosition: 'left',
contentComponent: MyLeftDrawer
}
);
const RightDrawer = createDrawerNavigator(
{
Drawer: LeftDrawer,
},
{
getCustomActionCreators: (route, stateKey) => { return { toggleRightDrawer: () => DrawerActions.toggleDrawer({ key: stateKey }) }; },
drawerPosition: 'right',
contentComponent: MyRightDrawer
}
);
export const RootNavigator = createStackNavigator(
{
Login: Login,
Home: RightDrawer
},
{
initialRouteName: 'Login',
navigationOptions: { header: null, gesturesEnabled: false }
}
);
键是getCustomActionCreators。它允许您从MyStackNavigator
中的任何屏幕调用函数,如下所示:this.props.navigation.toggleLeftDrawer();
。
答案 1 :(得分:1)
这是我的解决方法
第1步:创建两个抽屉式导航并将其嵌套在一起</ p>
第2步:将第一个抽屉式导航存储在其他位置(单人)
// Drawer 1
import ContentLeftMenu from '@components/ContentLeftMenu';
import { createDrawerNavigator } from '@react-navigation/drawer';
import * as React from 'react';
import DrawerCart from './DrawerCart';
import { setNavigationDrawerHome } from './RootNavigation';
import { isTablet } from 'react-native-device-info';
import MainStack from './MainStack';
const Drawer = createDrawerNavigator();
export default function DrawerHome() {
return (
<Drawer.Navigator
initialRouteName="DrawerCart"
drawerContent={() => <ContentLeftMenu />}
screenOptions={({ navigation, route }) => {
setNavigationDrawerHome(navigation)
}}
>
<Drawer.Screen name="DrawerCart" component={isTablet ? DrawerCart : MainStack} />
</Drawer.Navigator>
);
}
// Drawer 2
import CartScreen from '@features/cart/CartScreen';
import { createDrawerNavigator } from '@react-navigation/drawer';
import * as React from 'react';
import MainStack from './MainStack';
const Drawer = createDrawerNavigator();
export default function DrawerCart(props) {
return (
<Drawer.Navigator
initialRouteName="MainStackCart"
drawerContent={() => <CartScreen />}
drawerPosition='right'
>
<Drawer.Screen name="MainStackCart" component={MainStack} />
</Drawer.Navigator>
);
}
// set navigation of drawer 1 with navigationDrawerHome
let navigationDrawerHome = null
export const setNavigationDrawerHome = (navigation) => {
navigationDrawerHome = navigation
}
export const getNavigationDrawerHome = () => {
return navigationDrawerHome
}
当我在Mainstack中使用时,当我打开左侧的Drawer 1时,我使用的是NavigationDrawerHome,而抽屉2则使用导航道具
const Stack = createStackNavigator();
function MainStack() {
const navigationDrawerHome = getNavigationDrawerHome()
return (
<Stack.Navigator
screenOptions={({ navigation, route }) => ({
headerLeft: () => <HeaderLeft />,
headerTitleAlign: 'center',
})}>
<Stack.Screen
name="home_user_tab"
component={HomeUserTabs}
options={({ navigation, route }) => ({
headerLeft: () => {
return (
<ButtonIcon
onPress={() => navigationDrawerHome.openDrawer()}
style={styles.buttonLeft}
icon={images.ic_left_menu}
/>
)
},
headerTitle: () => <LogoHeader />,
headerRight: () => (<HeaderCardSearch
navigation={navigation}
/>),
// header: null
})}
/>
</Stack.Navigator>
);
}
const HeaderCardSearch = (props) => {
const { navigation } = props;
return (
<View style={styles.headerRight}>
<ButtonIcon
onPress={() => navigation.openDrawer()}
style={styles.buttonCart}
icon={images.ic_cart}
/>
<ButtonIcon
onPress={() => navigate('search')}
style={styles.buttonSearch}
icon={images.ic_search}
/>
</View>
)
};
答案 2 :(得分:0)
我设法通过编程方式打开了两个抽屉:
// Opens left drawer
this.props.navigation.openDrawer();
// Opens right drawer
this.props.navigation.dangerouslyGetParent().dangerouslyGetParent().openDrawer();
我的导航容器如下所示:
static container = (): NavigationContainer => createDrawerNavigator({
right: createDrawerNavigator({
left: DeviceControlContainer
}, {
contentComponent: HistoryDrawerContainer,
overlayColor: drawerOverlayColor()
})
}, {
drawerPosition: 'right',
overlayColor: drawerOverlayColor(),
navigationOptions: DeviceControlScreen.navigationOptions,
contentComponent: DeviceControlDrawer
});
答案 3 :(得分:0)
得益于Anh Devit解决方案的启发,这是我的。我在没有Stack Navigator的情况下在应用程序中使用了标题栏,因此必须走些许不同的路线。
对于我的RootNavigator
,我将标题放在第一个抽屉上方。我使用useState
,所以当我将导航对象作为道具传递时,AppHeader
可以在初始化抽屉后正确地重新渲染。
import React, { useState } from "react";
import { NavigationContainer } from "@react-navigation/native";
import LeftDrawer from "./LeftDrawer";
import AppHeader from "./AppHeader";
const RootNavigator = () => {
const [navigationLeftDrawer, setNavigationLeftDrawer] = useState(null);
const [navigationRightDrawer, setNavigationRightDrawer] = useState(null);
return (
<NavigationContainer>
<AppHeader
navigationLeftDrawer={navigationLeftDrawer}
navigationRightDrawer={navigationRightDrawer}
/>
<LeftDrawer
navigationLeftDrawer={(navigation) =>
setNavigationLeftDrawer(navigation)
}
navigationRightDrawer={(navigation) =>
setNavigationRightDrawer(navigation)
}
/>
</NavigationContainer>
);
};
export default RootNavigator;
在这里,我正在创建LeftDrawer
,其中将嵌套RightDrawer
。注意在抽屉启动时设置navigationLeftDrawer
。另外,navigationRightDrawer
必须作为参数而不是道具来传递。
import React, { useContext } from "react";
import {
createDrawerNavigator,
DrawerContentScrollView,
DrawerItem,
} from "@react-navigation/drawer";
import RightDrawer from "./RightDrawer";
const LeftDrawer = ({ navigationLeftDrawer, navigationRightDrawer }) => {
const Drawer = createDrawerNavigator();
return (
<Drawer.Navigator
screenOptions={({ navigation }) => {
navigationLeftDrawer(navigation);
}}
drawerContent={(props) => {
const { navigate } = props.navigation;
return (<RightDrawerItems />)
);
}}
>
<Drawer.Screen
name="AccountDrawer"
component={RightDrawer}
initialParams={{ navigationRightDrawer }}
/>
</Drawer.Navigator>
);
export default LeftDrawer;
与RightDrawer
中的情况类似,将navigationRightDrawer
与正确的导航对象向上传递。
import React from "react";
const RightDrawer = ({ route }) => {
const Drawer = createDrawerNavigator();
const { navigationRightDrawer } = route.params;
return (
<Drawer.Navigator
drawerPosition="right"
screenOptions={({ navigation }) => {
navigationRightDrawer(navigation);
}}
drawerContent={(props) => {
const { navigate } = props.navigation;
return ( <RightDrawerItems />);
}}
>
{userAuth ? (
<>
<Drawer.Screen name={routes.dashboard} component={DashboardScreen} />
</>
) : (
<Drawer.Screen name={routes.home} component={HomeStack} />
)}
<Drawer.Screen name={routes.about} component={AboutScreen} />
<Drawer.Screen name={routes.language} component={LanguageScreen} />
</Drawer.Navigator>
);
};
export default RightDrawer;
最后,AppHeader
:
import React, { useContext } from "react";
const AppHeader = ({ navigationRightDrawer, navigationLeftDrawer }) => {
if (navigationRightDrawer == null || navigationLeftDrawer == null)
return null;
return (
<View style={styles.container}>
<Icon
name="menu"
color={colors.white}
onPress={() => {
navigationRightDrawer.closeDrawer();
navigationLeftDrawer.toggleDrawer();
}}
/>
{userAuth ? (
<TouchableWithoutFeedback
onPress={() => {
navigationLeftDrawer.closeDrawer();
navigationRightDrawer.toggleDrawer();
}}
>
<Image
style={styles.image}
source={{ uri: userProfile.profilePicture }}
/>
</TouchableWithoutFeedback>
) : (
<Icon
name="person"
color={colors.secondary}
onPress={() => navigationLeftDrawer.navigate(routes.login)}
/>
)}
</View>
);
};
export default AppHeader;