反应导航 - 反应本机 - 如何阻止嵌套在抽屉导航器内的堆栈导航器中的抽屉?

Ger*_*cca 5 react-native react-navigation react-navigation-drawer react-navigation-stack react-navigation-v6

在我的反应本机应用程序中,我有一个嵌套在抽屉导航器内的堆栈导航器。我希望在堆栈导航器页面中禁用抽屉。我正在使用反应导航 6。

\n

在文档(https://reactnavigation.org/docs/drawer-navigator/#options)中,我看到有两个选项:gestureEnabled\xe2\x80\x8bswipeEnabled\xe2\x80\x8b。但这些只能用于抽屉式屏幕,不能像我的情况那样用于堆叠式屏幕。

\n

我的代码如下:

\n
const Stack = createNativeStackNavigator<RootStackParamList>();\nconst Drawer = createDrawerNavigator<RootTabParamList>();\n\nconst loginStack = () => (\n  <Stack.Navigator>\n    <Stack.Screen name="LandingScreen" component={LandingScreen} options={{ headerShown: false }} />\n    <Stack.Screen name="LoginScreen" component={LoginScreen} options={{ headerShown: false }} />\n    <Stack.Screen\n      name="RegisterScreen"\n      component={RegisterScreen}\n      options={{ headerShown: false }}\n    />\n  </Stack.Navigator>\n);\n\nreturn (\n  <NavigationContainer>\n    <Drawer.Navigator\n      screenOptions={{\n        drawerStyle: { backgroundColor: \'white\' },\n        drawerPosition: \'right\',\n      }}\n    >\n      {!user ? (\n        <Drawer.Screen\n          name="PublicStack"\n          component={loginStack}\n          // options={{headerShown: false}}\n          options={({ route }) => {\n            const routeName = getFocusedRouteNameFromRoute(route);\n            if (\n              routeName === \'LandingScreen\' ||\n              routeName === \'LoginScreen\' ||\n              routeName === \'RegisterScreen\'\n            )\n              return { swipeEnabled: false, gestureEnabled: false };\n            return { swipeEnabled: true, gestureEnabled: true };\n          }}\n        />\n      ) : (\n        <>\n          <Drawer.Screen\n            name="Search cocktails"\n            component={HomeScreen}\n            options={{ header: () => <Header /> }}\n          />\n          <Drawer.Screen\n            name="Profile"\n            component={ProfileScreen}\n            initialParams={{ userParam: null }}\n            options={{ header: () => <Header /> }}\n          />\n          <Drawer.Screen\n            name="Publish a recipe"\n            component={PublishRecipeScreen}\n            options={{ header: () => <Header /> }}\n          />\n          <Drawer.Screen\n            name="Favorites"\n            component={FavoritesScreen}\n            options={{ header: () => <Header /> }}\n          />\n          <Drawer.Screen\n            name="Published recipes"\n            component={PublishedRecipesScreen}\n            options={{ header: () => <Header /> }}\n          />\n          <Drawer.Screen\n            name="Log out"\n            component={CustomDrawerContent}\n            options={{ header: () => <Header /> }}\n          />\n\n          <Drawer.Screen\n            name="CocktailDetailScreen"\n            component={CocktailDetailScreen}\n            options={{\n              header: () => <Header />,\n              drawerLabel: () => null,\n              title: undefined,\n            }}\n          />\n        </>\n      )}\n    </Drawer.Navigator>\n  </NavigationContainer>\n);\n\n
Run Code Online (Sandbox Code Playgroud)\n

我尝试直接在登录堆栈抽屉屏幕上设置上述选项,例如:

\n
<Drawer.Screen\n  name=\'PublicStack\'\n  component={loginStack}\n  options={{swipeEnabled: false, gestureEnabled: false}}} \n/>\n
Run Code Online (Sandbox Code Playgroud)\n

但没有用。

\n

我也看到了这个答案(How to disable Drawer inside Stack Navigatornested inside Drawer Navigator?)并尝试实现类似的东西(我的代码现在看起来像这样),但仍然不起作用。

\n

完整代码可以在这里找到: https: //github.com/coccagerman/mixr

\n

谢谢!

\n

Fra*_* M. 5

这些天我也被同样的事情困扰。我没有找到可用的解决方案getFocusedRouteNameFromRoute(route),并采取了不同的方法。

首先是在整个应用程序中屏蔽抽屉:

      <Drawer.Navigator screenOptions = {{ swipeEnabled: false }}>
        <Drawer.Screen name="Screen1" component={StackScreen1} />
        <Drawer.Screen name="Screen2" component={StackScreen2} />
      </Drawer.Navigator>
Run Code Online (Sandbox Code Playgroud)

然后,在您需要的屏幕上启用抽屉,如下所示:

      useFocusEffect(
        useCallback((() => {
          // From a Stack screen, the Drawer is accessed.
          const parent = navigation.getParent()
          parent?.setOptions({ swipeEnabled: true })
          // It returns to the initial state.
          return () => parent?.setOptions({ swipeEnabled: false })
        }, [navigation])
      )
Run Code Online (Sandbox Code Playgroud)

如果您必须在许多屏幕上启用抽屉,则可以以相反的方式完成。在整个应用程序中启用抽屉,并仅在所需的应用程序中阻止它。

我知道这可能不是最好的解决方案,但我希望它对您有所帮助。致敬!