1.首先可以参考官方例子:
https://reactnavigation.org/docs/en/drawer-based-navigation.html
这个是最简单的
这个是官方GitHub例子:
https://github.com/react-navigation/react-navigation/blob/master/examples/NavigationPlayground/js/Drawer.js
当然这个也是比较简单的,只是通过openDrawer()来启动
组件属性总结:
https://blog.csdn.net/u010418640/article/details/80737330
2.结合tab bar
如果结合tab bar则变复杂了很多,因为我点击drawer里面的item时要跳转到对应的tab上,就不能简单使用openDrawer()来启动了,而且简单drawer不会遮挡下面的tab bar.
好在发现了一个女程序员写的例子,解决了我这个问题:
先给出地址:https://readybytes.in/blog/how-to-integrate-tabs-navigation-drawer-navigation-and-stack-navigation-together-in-react-navigation-v2
gitLab:https://gitlab.com/readybytes/ReactNavigationExampleVersion2
3.我的代码分析:
export const DrawerStack = createDrawerNavigator({
HOME: {
screen: TabNavigator,
},
},
{
initialRouteName: 'HOME',
contentComponent: DrawerScreen,
contentOptions: {
activeTintColor: '#e91e63',
},
style:{
backgroundColor: '#dfe04d',
},
});
入口改为DrawerStack,里面装tabNavigation, tabNavigation里面再装StackNavigation
里面用到contentComponent: DrawerScreen,这里导入了DrawerScreen页面组件.也就是这个Drawer里面是一个自定义页面.还有调整背景在DrawerStack里面调,进入到DrawerScreen不能调整.
调用:
只需要在栈中的页面调用即可,openDrawer()后会使用DrawerScreen
<Button onPress={() => this.props.navigation.openDrawer()} title="Open drawer" />
我的DrawerScreen:先放效果图:
import React, {Component} from 'react';
import {NavigationActions} from 'react-navigation';
import PropTypes from 'prop-types';
import {ScrollView, Text, View, StyleSheet, Image, TouchableOpacity} from 'react-native';
import { DrawerActions } from 'react-navigation';
import styles from '../styles/index';
class DrawerScreen extends Component {
navigateToScreen = (route) => () => {
const navigateAction = NavigationActions.navigate({
routeName: route
});
this.props.navigation.dispatch(navigateAction);
this.props.navigation.dispatch(DrawerActions.closeDrawer())
}
_cancleDrawer=function() {
this.props.navigation.closeDrawer()
}
render () {
return (
<View style={style.rootContainer}>
<View style={style.head}>
<Image source={require('../img/menu_header.png')} style={{resizeMode:'contain'}} />
</View>
<View style={style.head_bar}>
<TouchableOpacity onPress={() =>this._cancleDrawer()}>
<Image source={require('../img/menu_cancle.png')} />
</TouchableOpacity>
<Image source={require('../img/menu_inbox.png')} style={style.inboxStyle}/>
<Text style={{marginTop:10, fontWeight:'bold'}}>INBOX</Text>
</View>
<ScrollView>
<View>
<TouchableOpacity onPress={this.navigateToScreen('Home')}>
<View style={styles.menuItem}>
<Image source={require('../img/menu_home.png')} style={style.listImage}/>
<Text style={style.textStyle}>
Home
</Text>
</View>
</TouchableOpacity>
<TouchableOpacity onPress={this.navigateToScreen('Schedule')}>
<View style={styles.menuItem}>
<Image source={require('../img/menu_schedule.png')} style={style.listImage}/>
<Text style={style.textStyle}>
SCHEDULE
</Text>
</View>
</TouchableOpacity>
<TouchableOpacity onPress={this.navigateToScreen('Booking')}>
<View style={styles.menuItem}>
<Image source={require('../img/menu_booking.png')} style={style.listImage}/>
<Text style={style.textStyle}>
BOOKING
</Text>
</View>
</TouchableOpacity>
<TouchableOpacity onPress={this.navigateToScreen('Member')}>
<View style={styles.menuItem}>
<Image source={require('../img/menu_member.png')} style={style.listImage}/>
<Text style={style.textStyle}>
MEMBER
</Text>
</View>
</TouchableOpacity>
<TouchableOpacity onPress={this.navigateToScreen('SettingScreen')}>
<View style={styles.menuItem}>
<Image source={require('../img/menu_setting.png')} style={style.listImage}/>
<Text onPress={this.navigateToScreen('SettingScreen')} style={style.textStyle}>
SETTING
</Text>
</View>
</TouchableOpacity>
</View>
</ScrollView>
</View>
);
}
}
DrawerScreen.propTypes = {
navigation: PropTypes.object
};
const style = StyleSheet.create({
rootContainer:{
flex: 1,
flexDirection: 'column'
},
head:{
marginTop: 30,
alignItems: 'center',
justifyContent: 'center'
},
head_bar:{
flexDirection: 'row',
height:50
},
inboxStyle:{
marginLeft: 120,
},
listStyle:{
flex: 1,
marginTop:10
},
textStyle:{
marginTop:10,
marginLeft: 10,
fontWeight: 'bold',
textAlign:'center',
},
listImage:{
marginLeft:50
}
})
export default DrawerScreen;
几个要点:
一.核心实现跳转到相应的tab:
navigateToScreen = (route) => () => {
const navigateAction = NavigationActions.navigate({
routeName: route
});
this.props.navigation.dispatch(navigateAction);
this.props.navigation.dispatch(DrawerActions.closeDrawer())
}
二.onPress问题:
有两种:
如果没有返回,调用的是类,则要这样:
<TouchableOpacity onPress={this.navigateToScreen('Member')}>
第二种有返回的时候调用,一般调用的是function:
<TouchableOpacity onPress={() =>this._cancleDrawer()}>
(_fooFunc()表示私有)
类写在() =>中会发现跳转不了.function写在onPress={this._cancleDrawer()}会looping错误或者其他异常.因为onPress在render中会被渲染,onPress={this._cancleDrawer()}这样写会直接执行this的内容.
三.style UI:
flexDirection: 'column'
这个可以控制控件排列.
注意同级控件如果有一个加了flex,其他即使没有加flex,也会按照比例排开,所以要注意,不是什么情况都加flex的.
可以写一个单独的style,其他页面import进去后,可以直接style.xxx使用,简单直接,也可以复用.