如何在React Navigation中的堆栈导航内添加抽屉

时间:2018-09-23 20:07:09

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

我正在从事“登录/注册应用程序”之类的实践项目,并且正在使用来自反应导航的堆栈导航,并且运行良好,

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

This is What I want to look on my Dashboard Screen

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 />
        );
      }
    }

Dashboard.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',
            },
        }

3 个答案:

答案 0 :(得分:4)

从右侧显示抽屉。

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

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

从标题的按钮调用DrawerNavigation。

toggleDrawerDashboard.js的标题中添加一个按钮。您可以在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',
      },
    }
  }

您可以将按钮更改为“可触摸不透明度”或其他按钮。

使用另一个导航器包装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.

答案 1 :(得分: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上的物理后退按钮返回登录屏幕)。
  • 然后我们在右侧创建一个带有两个屏幕和一个汉堡图标的抽屉。
  • “主页”的子屏幕应位于“主页”堆栈内,并且与通知的屏幕相同。

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

答案 2 :(得分:1)

对于那些在 react-navigation 5.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中进行了解释。