【问题标题】:How to add a Drawer Inside Stack Navigation in React Navigation如何在 React Navigation 中的 Stack Navigation 中添加抽屉
【发布时间】:2018-09-23 20:07:09
【问题描述】:

我正在做一个像登录/注册应用程序这样的实践项目,我正在使用 react-navigations 中的堆栈导航,它运行良好,

现在,当用户登录时,他应该被重定向到仪表板屏幕,我希望在标题右侧有一个抽屉“我还添加了一个屏幕截图”,并且我也在 Stack 中创建了仪表板屏幕导航我不知道如何在堆栈导航中添加抽屉 我只想在仪表板屏幕上添加抽屉以便任何人都可以提供帮助?谢谢

App.js(我在其中添加了所有堆栈屏幕)

    import React from 'react';

    import { createStackNavigator, createDrawerNavigator } from 'react-navigation';

    import HomeScreen from './screens/HomeScreen';
    import LoginScreen from './screens/LoginScreen';
    import RegisterScreen from './screens/RegisterScreen';
    import Dashboard from './screens/Dashboard';

    const StackNavigation = createStackNavigator({
      HomeStack: HomeScreen,
      LoginStack: LoginScreen,
      RegisterStack: RegisterScreen,
      DashboardStack: Dashboard,

    }, {
        initialRouteName: 'HomeStack',
      });

      const DrawerNav = createDrawerNavigator({
        DashboardStack: Dashboard,
      })


    export default class App extends React.Component {
      render() {
        return (
          <StackNavigation />
        );
      }
    }

仪表板.js

    import React from 'react';
    import { Text, View, StyleSheet, TouchableOpacity } from 'react-native';

    import Icon from 'react-native-vector-icons/FontAwesome';

    export default class Dashboard extends React.Component {

        static navigationOptions = {

            headerTitle: 'Dashboard',
            headerLeft: null,

            headerTitleStyle: {
                flex: 1,
                color: '#fff',
                textAlign: 'center',
                alignSelf: 'center',
                fontWeight: 'normal',
            },

            headerStyle: {
                backgroundColor: '#b5259e',
            },
        }

【问题讨论】:

    标签: android react-native react-native-android react-navigation react-navigation-drawer


    【解决方案1】:

    从右侧显示抽屉。

    在创建抽屉导航器时添加drawer Position参数。

    const DrawerNav = createDrawerNavigator({
      DashboardStack: Dashboard, 
    },
    {
      drawerPosition: 'right'
    });
    

    从标题按钮调用 DrawerNavigation。

    Dashboard.js 中为toggleDrawer 的标题添加一个按钮。您可以在navigationOptions中获取如下导航实例;

    class Dashboard extends React.Component {
      static navigationOptions = ({navigation, navigationOptions}) => {
        return {
          headerTitle: 'Dashboard@@',
          headerLeft: <Text>Left</Text>,
          headerRight: (
            <Button onPress = {navigation.toggleDrawer}
            title="Menu"
            color="#fff">
              <Text>Menu</Text>
            </Button>
          ),
          headerTitleStyle: {
            flex: 1,
            color: '#fff',
            textAlign: 'center',
            alignSelf: 'center',
            fontWeight: 'normal',
          },
    
          headerStyle: {
            backgroundColor: '#b5259e',
          },
        }
      }

    您可以将按钮更改为 Touchable Opacity 或其他按钮。

    使用另一个导航器包装 AuthStackNavigationDrawerNavigation

    使用createSwitchNavigation 或其他方法包装您的导航并导出。

    // App.js
    
    import React from 'react';
    
    import {
      createStackNavigator,
      createDrawerNavigator,
      createSwitchNavigator,
    } from 'react-navigation';
    
    import HomeScreen from './srcs/screens/Home';
    import Dashboard from './srcs/screens/Dashboard';
    
    const AuthStackNavigation = createStackNavigator({
      HomeStack: HomeScreen,
      LoginStack: HomeScreen,
      RegisterStack: HomeScreen,
    }, {
      initialRouteName: 'HomeStack',
    })
    
    const DashboardStack = createStackNavigator({ // For header options
      Dashboard: Dashboard
    })
    
    const DrawerNav = createDrawerNavigator({
      DashboardStack: DashboardStack,
      SecondScreen: Dashboard, // You should use another screen.
      ThirdScreen: Dashboard,
    })
    
    const MainNavigation = createSwitchNavigator({
      HomeDrawer: DrawerNav,
      AuthStack: AuthStackNavigation, // You will use this.props.navigation.replace('HomeDrawer') after login process.
    })
    
    export default MainNavigation // Stack, Drawer, Switch naviagtions return react component.

    【讨论】:

    • 我必须在哪里调用 DrawNav?就像我在 App.js 渲染中调用 StackNavigator 一样。
    • 我在应用程序中调用了与 StackNavigator 相同的 DrawNav,当我运行我的应用程序时,像这样“”我的仪表板显示了抽屉,但我的仪表板标题隐藏了,甚至没有滑动抽屉。
    • @IrshadAlam 我写了如何调用多重导航。你可以应用你想要的。你可以在你的DrawerNav 中放置更多的屏幕和控制作为我的例子。
    • 我和你在 App.js 文件中编码的一样,我在仪表板标题中添加了一个汉堡图标,当我通过 {this.props.navigation.toggleDrawer} 或 {this.props .navigation.navigate('DrawerOpen')} 我得到错误(未定义的不是对象 this.props.navigation)。我该怎么办?我希望它在按下/点击图标时打开带有一些组件的抽屉。谢谢
    • @IrshadAlam 我在笔记本电脑上测试后更新了我的答案。它将向您展示如何编辑标题的导航控制按钮以及如何通过 react-navigation 包装屏幕。祝你好运:)
    【解决方案2】:

    我刚刚创建了一个您可能需要的示例。

    import React, {Component} from 'react';
    import {
      StyleSheet,
      Button,
      Image,
      TouchableWithoutFeedback,
      View,
    } from 'react-native';
    import {
      createDrawerNavigator,
      createStackNavigator,
      StackActions,
      NavigationActions,
    } from 'react-navigation';
    
    
    class HomeScreen extends React.Component {
      render() {
        return (
            <View style={styles.container}>
              <Button
                  onPress={() => this.props.navigation.navigate('Notifications')}
                  title="Go to notifications"
              />
            </View>
        );
      }
    }
    
    class NotificationsScreen extends React.Component {
      render() {
        return (
            <View style={styles.container}>
              <Button
                  onPress={() => this.props.navigation.navigate('Home')}
                  title="Go back home"
              />
            </View>
        );
      }
    }
    
    class LoginScreen extends Component {
      openDashboard = () => {
        const resetAction = StackActions.reset({
          index: 0,
          actions: [NavigationActions.navigate({routeName: 'Dashboard'})],
        });
        this.props.navigation.dispatch(resetAction);
      }
    
      render() {
        return (
            <View style={styles.container}>
              <Button
                  onPress={this.openDashboard}
                  title={'Login'}
              />
            </View>
        )
      }
    }
    
    const styles = StyleSheet.create({
      container: {
        flex: 1,
        justifyContent: 'center',
        paddingHorizontal: 20,
      },
      icon: {
        width: 24,
        height: 24,
      },
      menu: {
        marginRight: 8,
      }
    });
    
    const renderMenu = (navigation) => (
        <TouchableWithoutFeedback onPress={() => navigation.openDrawer()}>
          <Image
              source={require('./menu.png')}
              style={[styles.icon, styles.menu]}
          />
        </TouchableWithoutFeedback>
    )
    
    const Home = createStackNavigator({
      Home: {
        screen: HomeScreen,
        navigationOptions: ({navigation}) => ({
          title: 'Home',
          headerRight: renderMenu(navigation)
        }),
      }
    })
    
    const Notifications = createStackNavigator({
      Notifications: {
        screen: NotificationsScreen,
        navigationOptions: ({navigation}) => ({
          title: 'Notifications',
          headerRight: renderMenu(navigation)
        })
      }
    })
    
    const Dashboard = createDrawerNavigator(
        {
          Home: {
            screen: Home,
            navigationOptions: {
              drawerLabel: 'Home',
              drawerIcon: (
                  <Image
                      source={require('./chats-icon.png')}
                      style={styles.icon}
                  />
              ),
            }
          },
          Notifications: {
            screen: Notifications,
            navigationOptions: {
              drawerLabel: 'Notifications',
              drawerIcon: (
                  <Image
                      source={require('./notif-icon.png')}
                      style={styles.icon}
                  />
              ),
            }
          },
        },
        {
          drawerPosition: 'right'
        }
    );
    
    const App = createStackNavigator(
        {
          Login: LoginScreen,
          Dashboard: Dashboard
        },
        {
          initialRouteName: 'Login',
          headerMode: 'none'
        }
    )
    
    export default App;
    
    • 当用户按下 LoginScreen 上的登录按钮时,导航将被重置(这样用户就无法通过返回箭头或 android 上的物理返回按钮返回登录屏幕)。
    • 然后我们在右侧创建一个带有两个屏幕和一个汉堡图标的抽屉。
    • Home 的子屏幕应位于 Home 堆栈中,通知也应如此。

    您只需要添加缺少的图标。

    【讨论】:

    • 实际上我是 React Native 的新手,我感到困惑的是我有仪表板屏幕,我在右侧顶部标题上有图标,这就是我想知道的......当我点击汉堡图标打开一个小抽屉请检查我的 App.js 文件并让我知道我应该在哪里调用它?我应用了 Jeff Gu Kang 所做的更改,它正在工作我不知道我应该在哪里调用 DrawNav,以便唯一的仪表板屏幕可以访问抽屉。谢谢
    【解决方案3】:

    对于那些在react-navigation5.X中寻找解决方案的人,你可以这样做:

    抽屉导航器

    const ProductListWithDrawer = () => {
     return (
      <Drawer.Navigator initialRouteName="ProductList">
       <Drawer.Screen name="ProductList" component={screens.ProductList} />
       <Drawer.Screen name="ProductDetail" component={screens.ProductDetailScreen} />
      </Drawer.Navigator>
      );
     };
    

    Stack Navigator(应该包裹在Navigation Container中)

    <Stack.Navigator initialRouteName="Dashboard" screenOptions={{ headerShown: false }}>
      <Stack.Screen name="Dashboard" component={screens.Dashboard} />
      <Stack.Screen name="Loading" component={screens.Loading} />
      <Stack.Screen name="Chat" component={screens.Chat} />
      <Stack.Screen name="ProductListWithDrawer" component={ProductListWithDrawer} /> //our drawer
    </Stack.Navigator>
    

    基本上,这应该可以完成工作。这里可能存在的另一件事是在使用参数导航到抽屉导航器内的那些屏幕时。在这种情况下,可以这样做:

    navigation.navigate("ProductListWithDrawer", {
                  screen: "ProductList",
                  params: { user: "Alex"},
                });
    

    这在Nesting navigators中也有解释。

    【讨论】:

      猜你喜欢
      • 2020-05-22
      • 1970-01-01
      • 1970-01-01
      • 2020-09-23
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多