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()來啟動
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的.