Jeśli masz problem ze zrozumieniem działania Drawer navigation, ten krótki tutorial pomoże Ci zaimplementować DrawerNavigator do swojej aplikacji.
Jeśli jeszcze nie masz zainstalowanej nawigacji w swoim projekcie, możesz to zrobić wpisując polecenia:
npm install --save react-navigation
npm install --save react-native-gesture-handler
react-native link react-native-gesture-handler
Zacznijmy od stworzenia folderu components, w którym umieścimy pliki DrawerNavigator.js, HomeScreen.js, Screen1.js, Screen2.js, Screen3.js.
Standardowo plik App.js wygląda tak:
import React, {Component} from 'react';
import DrawerNavigator from './components/DrawerNavigator';
export default class App extends Component {
render() {
return (
<DrawerNavigator />
);
}
}
Czas na stworzenie DrawerNavigatora:
DrawerNavigator.js
import React, {Component} from 'react';
import { createDrawerNavigator, createAppContainer} from 'react-navigation';
import HomeScreen from './HomeScreen';
import Screen1 from './Screen1';
import Screen2 from './Screen2';
import Screen3 from './Screen3';
const MyDrawerNavigator = createDrawerNavigator({
Home: {screen: HomeScreen},
Screen1: {screen: Screen1},
Screen2: {screen: Screen2},
Screen3: {screen: Screen3},
},
{
initialRouteName: 'Home',
drawerWidth: 300,
drawerPosition: 'left',
}
);
const AppContainer = createAppContainer(MyDrawerNavigator);
export default class DrawerNavigator extends Component {
render() {
return <AppContainer />;
}
}
Każdej z 4 opcji nawigatora przyporządkowujemy ekran o odpowiedniej nazwie. Jako domyślny ustawimy ekran przyporządkowany do nazwy Home, przypisując go do initialRouteName. Szerokość nawigatora ustawimy na 300 i ustawimy go z lewej strony ekranu głównego.
Na ekranie głównym natomiast umieścimy napis: To jest ekran startowy oraz ikonkę, po dotknięciu której z lewej strony wysunie się nasz nawigator.
HomeScreen.js
import React, {Component} from 'react';
import {StyleSheet, Text, View, TouchableHighlight} from 'react-native';
import { DrawerActions, } from 'react-navigation';
export default class HomeScreen extends Component {
static navigationOptions = {
drawerLabel: 'Home',
};
render() {
return (
<View style={styles.view}>
<TouchableHighlight style={styles.touchableHighlight} underlayColor={'rgba(0,0,0,0.8)'}
onPress={() => { this.props.navigation.dispatch(DrawerActions.openDrawer()); }}>
<Text style={styles.open}>OPEN </Text>
</TouchableHighlight>
<Text style={styles.text}> This is homescreen </Text>
</View>
);
}
}
Pozostałe ekrany będą miały różne kolory oraz przycisk, który kierować będzie do ekranu głównego:
Screen1.js, Screen2.js Scree3.js
import React, {Component} from 'react';
import {StyleSheet, Text, View, TouchableHighlight} from 'react-native';
export default class Screen1 extends Component {
render() {
return (
<View style={styles.view}>
<Text style={styles.text}> This is screen 1 </Text>
<TouchableHighlight onPress={() => this.props.navigation.goBack() } style={styles.touchableHighlight} underlayColor={'#f1f1f1'}>
<Text style={styles.text}>Go back</Text>
</TouchableHighlight>
</View>
);
}
}
Teraz zostało już tylko ustawić odpowiednie style.
HomeScreen,js
const styles = StyleSheet.create({
view: {
flex: 1,
alignItems: 'center',
justifyContent: 'center',
backgroundColor: 'white',
},
text: {
fontSize: 26,
color: 'purple'
},
touchableHighlight: {
width: 50,
height: 50,
backgroundColor: 'red',
borderRadius: 50,
alignItems: 'center',
justifyContent: 'center',
position: 'absolute',
left: 10,
top: 10,
},
open: {
color: 'white',
fontSize: 16,
fontWeight: 'bold',
},
});
Screen1.js
const styles = StyleSheet.create({
view: {
flex: 1,
alignItems: 'center',
justifyContent: 'center',
backgroundColor: 'yellow',
},
text: {
fontSize: 20,
color: 'black',
},
touchableHighlight: {
backgroundColor: 'orange',
paddingVertical: 20,
paddingHorizontal: 50,
margin: 10,
}
});
Efekt będzie taki:
Customize DrawerNavigator // Personalizowanie Drawer Nawigatora
A co jeśli chcielibyśmy dodać do naszego nawigatora więcej elementów? Przydałby mu się nagłówek, jakieś zdjęcie albo stopka. W takim przypadku możemy ustawić własny, spersonalizowany komponent, który będzie służył jako DrawerNavigator. W tym celu odrobinę zmodyfikujemy nasz nawigator:
DrawerNavigator.js
...
{
initialRouteName: 'Home',
contentComponent: ContentComponent,
drawerWidth: Dimensions.get('window').width,
drawerPosition: 'left',
drawerBackgroundColor: 'transparent',
}
...
Teraz możemy stworzyć dowolny wygląd, dodając np. nagłówek ze zdjęciem i odnośniki do innych ekranów, a także odpowiednie ikonki. W zasadzie, możemy tu dodać co chcemy, co sprawia, że nasz nawigator może być naprawdę ciekawy. Przykładowy kod poniżej:
ContentComponent.js
export default class ContentContainer extends Component {
render() {
return (
<TouchableOpacity activeOpacity={1} style={styles.drawerTransparent} onPress={() => this.props.navigation.goBack()}>
<TouchableOpacity activeOpacity={1} style={styles.drawer} disabled={false}>
<ScrollView>
<View style={styles.header}>
<Image source={require('../face4.jpg')} style={styles.headerImage}/>
<Text style={[styles.text, {color: 'white'}]}>My Profile</Text>
</View>
<TouchableHighlight underlayColor={'rgba(0,0,0,0.2)'} onPress={() => this.props.navigation.navigate('Screen1')}>
<View style={styles.row}>
<Image source={require('../icons/contact.jpg')} style={styles.headerImage} />
<Text style={styles.text}>Contacts</Text>
</View>
</TouchableHighlight>
<TouchableHighlight underlayColor={'rgba(0,0,0,0.2)'} onPress={() => this.props.navigation.navigate('Screen2')}>
<View style={styles.row}>
<Image source={require('../icons/user.jpg')} style={styles.headerImage} />
<Text style={styles.text}>Add Contact</Text>
</View>
</TouchableHighlight>
<TouchableHighlight underlayColor={'rgba(0,0,0,0.2)'} onPress={() => this.props.navigation.navigate('Screen3')}>
<View style={styles.row}>
<Image source={require('../icons/group.jpg')} style={styles.headerImage} />
<Text style={styles.text}>Add Group</Text>
</View>
</TouchableHighlight>
<View style={styles.line}></View>
...
</View>
</TouchableHighlight>
</ScrollView>
</TouchableOpacity>
</TouchableOpacity>
);
}
}
Efekt: