[React Native] Navigation (Drawer)

2020. 12. 28. 00:29React/React Native

1. Navigation

React Native는 지속적으로 개발되어 가고 있기 때문에, 버전별 사용법이 다를 수 있다. 그렇기 때문에 공식 문서(reactnavigation.org/docs/getting-started)를 확인하여 제작하는 것을 권장한다.

 

설치된 목록은 package.json 파일에서 확인할 수 있다.

// Navigation 설치
npm install @react-navigation/native

// 의존성 설치
npm install react-native-reanimated react-native-gesture-handler react-native-screens react-native-safe-area-context @react-native-community/masked-view

npx pod-install

 

 

 

2. Drawer Navigator

1) Drawer Navigator 설치

Drawer Navigation을 이용하게 되면 Header Bar가 없어진다. 만약 필요할 경우, 직접 컴포넌트를 이용하여 Header Bar를 생성해주어야 한다.

npm install @react-navigation/drawer

2) Linking

Drawer Navigator도 Stack Navigator와 마찬가지로 NavigationContainer로 감싸주어야 하며, Drawer Navigator를 사용하기 위해 createDrawerNavigator 메서드를 이용해야한다.

 

순차적으로 진행하기 위해서는 다음의 항목을 처리해준다.

  • 필요한 모듈 import
  • App.js NavigationContainer, Drawer.Navigator 정의

 

import 'react-native-gesture-handler';
import { NavigationContainer } from '@react-navigation/native';
import { createDrawerNavigator } from '@react-navigation/drawer';

// 별도의 js 파일 import
import DrawerHomeScreen from './src/home_drawer';
import DrawerUserScreen from './src/user_drawer';
// App.js
      <NavigationContainer>
        <Drawer.Navigator>
          <Drawer.Screen
            name="Home"
            component={DrawerHomeScreen}
          />
          <Drawer.Screen
            name="User"
            component={DrawerUserScreen}
          />
        </Drawer.Navigator>
      </NavigationContainer>

Drawer Navigation

2) Style 설정

DrawerNavigator의 경우에는 공통으로 사용되는 부분이기에 Drawer.Navigator 내부에 정의가 된다.

import { createDrawerNavigator, DrawerContentScrollView, DrawerItemList, DrawerItem } from '@react-navigation/drawer';

CustomDrawerContent = (props) => {
  return (
    <DrawerContentScrollView {...props}>
      <DrawerItemList {...props}/>
      <DrawerItem
        label="help"
        onPress={()=>Linking.openURL('https://www.google.com')}
      />
      <DrawerItem
        label='Info'
        onPress={()=>alert('Info Window')}
      />
    </DrawerContentScrollView>
  )
}

class App extends Component {
 
  render() {
    return (
      
      <NavigationContainer>
        <Drawer.Navigator
          initialRouteName="Home"
          drawerType="front"          
          drawerPosition="right"
          drawerStyle={{ // 스타일
            backgroundColor: '#C6CBEF',
            width: 200
          }}
          drawerContentOptions={{ // 버튼 스타일
            activeTintColor: 'red',
            activeBackgroundColor: 'skyblue'
          }}
          drawerContent={props => <CustomDrawerContent {...props}/>}
        >
          <Drawer.Screen
            name="Home"
            component={DrawerHomeScreen}
          />
          <Drawer.Screen
            name="User"
            component={DrawerUserScreen}
          />
        </Drawer.Navigator>
      </NavigationContainer>
    )
  }
}
코드 설명
drawerType Drawer 화면 설정 (front, slide, permanent) 
drawerPosition Drawer 위치 설정
drawerStyle Drawer 스타일 설정
drawerContentOptions Drawer 버튼 스타일 설정
drawerContent 리액트 요소를 반환

drawerContent의 경우 자동으로 ScrollView가 적용이 되며, 4개의 인자(props)가 필요하다.

  • 어떤 route가 있는지 알기 위한 State
  • Navigation
  • Drawer Option
  • Drawer가 닫혔는지 열려있는지의 상태

 

그림을 삽입하는 방법은 3가지가 존재한다.

  • Drawer.Navigator drawerContent (1)
  • Drawer.Screen Options (2)
  • Drawer.Screen Component (3)

(1)

import { createDrawerNavigator, DrawerContentScrollView, DrawerItemList, DrawerItem } from '@react-navigation/drawer';
import LogoTitle from './src/logo';

CustomDrawerContent = (props) => {
  return (
    <DrawerContentScrollView {...props}>
      <DrawerItemList {...props}/>
      <DrawerItem
        label="help"
        onPress={()=>Linking.openURL('https://www.google.com')}
      />
      <DrawerItem
        label='Info'
        onPress={()=>alert('Info Window')}
        icon={()=> <LogoTitle/>}
      />
    </DrawerContentScrollView>
  )
}

class App extends Component {
 
  render() {
    return (
      
      <NavigationContainer>
        <Drawer.Navigator
          initialRouteName="Home"
          drawerType="front"          
          drawerPosition="right"
          drawerStyle={{ // 스타일
            backgroundColor: '#C6CBEF',
            width: 200
          }}
          drawerContentOptions={{ // 버튼 스타일
            activeTintColor: 'red',
            activeBackgroundColor: 'skyblue'
          }}
          drawerContent={props => <CustomDrawerContent {...props}/>}
        >
          <Drawer.Screen
            name="Home"
            component={DrawerHomeScreen}
          />
          <Drawer.Screen
            name="User"
            component={DrawerUserScreen}
          />
        </Drawer.Navigator>
      </NavigationContainer>
    )
  }
}

(2)

class App extends Component {
 
  render() {
    return (
      
...

          <Drawer.Screen
            name="Home"
            component={DrawerHomeScreen}
            options={{ // options를 이용한 이미지 삽입
              drawerIcon: () => (
                <Image
                  source={PictogramHome}
                  style={{width: 40, height: 40}}
                />
              )
            }}
          />
...

(3)

이 방법을 사용할 경우, 이는 DrawerUserScreen 클래스가 호출될 경우에 동작을 하기 때문에 첫 Drawer Navigation에는 확인할 수 없다. 

/**
 * Sample React Native App
 * https://github.com/facebook/react-native
 *
 * @format
 * @flow
 */

import 'react-native-gesture-handler';
import React, { Component } from 'react';
import { View, Text, Button, Image } from 'react-native';
import PictogramUser from './assets/pics/homeicon.png'

class DrawerUserScreen extends Component {

    drawStyle = () => {
        this.props.navigation.setOptions({
            drawerIcon: () => (
                <Image
                  source={PictogramUser}
                  style={{width: 40, height: 40}}
                />
              )
        })
    }

    render() {

        this.drawStyle();

        return (
            <View style={{
                flex: 1,
                alignItems: 'center',
                justifyContent: 'center'
            }}>
                <Text>User Screen</Text>
                <Button
                    title='To Home Screen'
                    onPress={()=>{
                        this.props.navigation.navigate('Home')
                    }}
                />
            </View>
        )
    }
}

export default DrawerUserScreen;

3) Customizing

만약 Drawer Navigator를 커스터마이징을 한다면, 먼저 Drawer Navigator를 구성할 파일을 생성한 뒤, App.js 파일에 import하고

drawerContent의 구성요소로 삽입(1)해주어야한다. 이 후 Drawer Navigator 구성 파일을 편집(2)하여 커스터마이징을 진행해주면 된다.

 

(1)

import SideDrawer from './src/my_drawer';

class App extends Component {
 
  render() {
    return (
      
      <NavigationContainer>
        <Drawer.Navigator
          initialRouteName="Home"
          drawerType="front"
          drawerPosition="right" 
          drawerStyle={{ // 스타일
            backgroundColor: '#C6CBEF',
            width: 200
          }}
          drawerContentOptions={{ // 버튼 스타일
            activeTintColor: 'red',
            activeBackgroundColor: 'skyblue'
          }}
          drawerContent={props => <SideDrawer {...props}/>} 
        >
...

(2)

import 'react-native-gesture-handler';
import React, { Component } from 'react';
import { View, Text, StyleSheet, Image, ScrollView } from 'react-native';
import Logo from './assets/pics/homeicon.png'
import { CommonActions } from '@react-navigation/native' // CommonActions

class SideDrawer extends Component {
 
    navigateToScreen = (route) => () => {
        this.props.navigation.dispatch(
            CommonActions.navigate({ // 특정 route로 이동할 수 있도록 도와주는 메서드
                name: route,
                params: { }
            })
        )
    }

  render() {
    return (
        <View style={styles.container}>
            <ScrollView>
                <View>
                    <View style={styles.imageContainer}>
                        <Image
                            source={Logo}
                            style={{width: 40, height: 40}}
                        />
                    </View>
                    <Text style={styles.sectionHeading}>Section 1</Text>
                    <View style={styles.addSectionStyle}>
                        <Text onPress={this.navigateToScreen('Home')} style={styles.navItemStyle}>Home</Text>
                        <Text onPress={this.navigateToScreen('User')} style={styles.navItemStyle}>User</Text>
                        <Text onPress={()=>alert('Help')} style={styles.navItemStyle}>Help</Text>
                        <Text onPress={()=>alert('Info')} style={styles.navItemStyle}>Info</Text>
                    </View>
                </View>
            </ScrollView>
            <View style={{paddingLeft: 10, paddingBottom: 30}}>
                <Text>Copyright @ Wintho, 2020.</Text>
            </View>
        </View>
    )
  }
}

const styles = StyleSheet.create({
    container: {
        flex: 1,
        paddingTop: 80
    },
    imageContainer: {
        alignItems: 'center',
        paddingTop: 50
    },
    sectionHeading: {
        color: '#fff',
        backgroundColor: '#ef9de4',
        paddingVertical: 10,
        paddingHorizontal: 15,
        fontWeight: 'bold'
    },
    addSectionStyle: {
        backgroundColor: '#04b6ff'
    },
    navItemStyle: {
        padding: 10,
        color: '#fff'
    }
})

export default SideDrawer;
728x90

'React > React Native' 카테고리의 다른 글

[React Native] React Native Vector Icons  (0) 2020.12.31
[React Native] Navigation (Tab)  (0) 2020.12.30
[React Native] Navigation (Stack)  (0) 2020.12.25
[React Native] Image, Modal  (0) 2020.12.25