๐Ÿ–‡๏ธ hanium

[React Native] Navigation์„ ์ด์šฉํ•œ ํ™”๋ฉด ์ „ํ™˜ / ๋„ค์ดํ‹ฐ๋ธŒ ์Šคํƒ·ํ•˜๋‹จ ํƒญ ๋„ค๋น„๊ฒŒ์ดํ„ฐ ํ•จ๊ป˜ ๊ตฌํ˜„

๊ธฐ๋ฎจ์ง€ 2022. 8. 9. 11:57
๊ตฌํ˜„ ํ™˜๊ฒฝ

Mac OS, ARM(M1)

React-native CLI

version 0.68.2

 

 

์„ค์น˜

$ cd [ํ”„๋กœ์ ํŠธ๋ช…]
$ yarn add @react-navigation/native
$ yarn add react-native-screens react-native-safe-area-context
$ cd ios
$ pod install

 

๋„ค๋น„๊ฒŒ์ดํ„ฐ์— ์ต์ˆ™ํ•˜์ง€ ์•Š์•„์„œ ์ฒ˜์Œ์— ์Šคํƒ์„ ๋ถ„๋ฆฌํ•ด์„œ ์ž‘์„ฑํ–ˆ๋‹ค.

 

App.js์—์„œ ๋„ค๋น„๊ฒŒ์ดํ„ฐ๋ฅผ ์‚ฌ์šฉํ•˜๊ณ ,

MainScreen.js์—์„œ ํ•˜๋‹จํƒญ ๋„ค๋น„๊ฒŒ์ดํ„ฐ๋ฅผ ์‚ฌ์šฉํ–ˆ๋‹ค.

 

๋„ค๋น„๊ฒŒ์ดํ„ฐ๊ฐ€ ๋ถ„๋ฆฌ๋˜์–ด ์žˆ์–ด ๊ตฌ์กฐ๊ฐ€ ํ•œ ๋ˆˆ์— ๋ณด์ด์ง€ ์•Š์•„์„œ ๋ฐ”๊พธ๊ณ  ์‹ถ์—ˆ๋‹ค.

 

 

 

App.js (์ˆ˜์ • ์ „)

import * as React from 'react';
import { NavigationContainer } from '@react-navigation/native';
import { createNativeStackNavigator } from '@react-navigation/native-stack';

import MainScreen from './android/screens/MainScreen'
import LikeScreen from './android/screens/LikeScreen'
import Cafe from './android/screens/Category/Cafe'
import Restaurant from './android/screens/Category/Restaurant'
import Drink from './android/screens/Category/Drink'
import Etc from './android/screens/Category/Etc'
import Random from './android/screens/Category/Random';

const Stack = createNativeStackNavigator();

export default function App() {
  return (
    <NavigationContainer>
      <Stack.Navigator>
        <Stack.Screen
          name="Main"
          component={MainScreen}
          options={{headerShown: false}}
        />
        <Stack.Screen
          name="Like"
          component={LikeScreen}
        />
        <Stack.Screen
          name="Cafe"
          component={Cafe}
        />
        <Stack.Screen
          name="Restaurant"
          component={Restaurant}
        />
        <Stack.Screen
          name="Drink"
          component={Drink}
        />
        <Stack.Screen
          name="Etc"
          component={Etc}
        />
        <Stack.Screen
          name="Random"
          component={Random}
        />
      </Stack.Navigator>
    </NavigationContainer>
  );
}

 

MainScreen.js (์ˆ˜์ • ์ „)

import * as React from 'react';
import {Text, TextInput, View, Button, Image, StyleSheet, ScrollView, TouchableOpacity} from 'react-native'
import { createBottomTabNavigator } from '@react-navigation/bottom-tabs';
import Icon from 'react-native-vector-icons/MaterialIcons'
import { useNavigation } from '@react-navigation/native';

import MapScreen from './MapScreen';
import CourseScreen from './CourseScreen';
import MyPageScreen from './MyPageScreen';

const Tab = createBottomTabNavigator();

function MainScreen(){
    return (
        <Tab.Navigator initialRouteName="Home" screenOptions={{tabBarActiveTintColot: '#fd8c00'}}>
            <Tab.Screen name="Home" component={HomeScreen} options={{
            title: 'Home',
            tabBarIcon: ({color, size}) => (
                <Icon name="home" color={color} size={size} />
            ),
            }}/>
            <Tab.Screen name="Map" component={MapScreen} options={{
            title: 'Map',
            tabBarIcon: ({color, size}) => (
                <Icon name="map" color={color} size={size} />
            ),
            }}/>
            <Tab.Screen name="Course" component={CourseScreen} options={{
            title: 'Course',
            tabBarIcon: ({color, size}) => (
                <Icon name="like" color={color} size={size} />
            ),
            }}/>
            <Tab.Screen name="My Page" component={MyPageScreen} options={{
            title: 'My Page',
            tabBarIcon: ({color, size}) => (
                <Icon name="settings" color={color} size={size} />
            ),
            }}/>
      </Tab.Navigator>
    );
}

function LikeButton() {
    const navigation = useNavigation();
    return (
        <TouchableOpacity activeOpacity={0.8} onPress={() => navigation.push('Like', { id: 1, })}>
          <Text style={{fontSize: 18, marginHorizontal: 10, marginVertical: 10}}>โค๏ธ</Text>
        </TouchableOpacity>
    );
}

function CafeButton() {
    const navigation = useNavigation();
    return (
        <TouchableOpacity activeOpacity={0.8} onPress={() => navigation.push('Cafe', { id: 2, })}>
          <Text style={{fontSize: 40, marginHorizontal: 20, marginVertical: 10}}>๐Ÿง</Text>
          <Text style={{fontSize: 16, marginHorizontal: 30}}>Cafe</Text>
        </TouchableOpacity>
    );
}

function RestaurantButton() {
    const navigation = useNavigation();
    return (
        <TouchableOpacity activeOpacity={0.8} onPress={() => navigation.push('Restaurant', { id: 3, })}>
          <Text style={{fontSize: 40, marginHorizontal: 23, marginVertical: 10}}>๐Ÿด</Text>
          <Text style={{fontSize: 16, marginHorizontal: 8}}>Restaurant</Text>
        </TouchableOpacity>
    );
}

function DrinkButton() {
    const navigation = useNavigation();
    return (
        <TouchableOpacity activeOpacity={0.8} onPress={() => navigation.push('Drink', { id: 4, })}>
          <Text style={{fontSize: 40, marginHorizontal: 20, marginVertical: 10}}>๐Ÿบ</Text>
          <Text style={{fontSize: 16, marginHorizontal: 25}}>Drink</Text>
        </TouchableOpacity>
    );
}

function EtcButton() {
    const navigation = useNavigation();
    return (
        <TouchableOpacity activeOpacity={0.8} onPress={() => navigation.push('Etc', { id: 5, })}>
          <Text style={{fontSize: 40, marginHorizontal: 20, marginVertical: 10}}>๐Ÿ‘€</Text>
          <Text style={{fontSize: 16, marginHorizontal: 33}}>Etc</Text>
        </TouchableOpacity>
    );
}

function RandomImage() {
    const navigation = useNavigation();
    return (
        <TouchableOpacity activeOpacity={0.8} onPress={() => navigation.push('Random', { id: 6, })}>
          <Image style={styles.place} source={require('../assets/logo.png')}/>
          <View style={styles.info}>
            <Text>์ œ๋ชฉ</Text>
            <Text>์„ค๋ช…๋ธ”๋ผ๋ธ”๋ผ</Text>
          </View>
        </TouchableOpacity>
    );
}

function HomeScreen() {
    return(
        <View style={{flex: 1, flexDirection: 'column', backgroundColor: 'white'}}>
            <View style={styles.searchBar}>
                <Image style={styles.logoStyle} source={require('../assets/logo.png')}/>
                <TextInput style={styles.input}
                placeholder="#๊ฒ€์ƒ‰์–ด๋ฅผ ์ž…๋ ฅํ•˜์„ธ์š”."
                autoCapitalize="none" />
                <TouchableOpacity activeOpacity={0.8}>
                    <Text style={{fontSize: 18, marginHorizontal: 5}}>๐Ÿ”Ž</Text>
                </TouchableOpacity>
                <LikeButton style={styles.buttonStyle}/>
            </View>
            <View style={styles.locationBar}>
                <Text>์šฉ์‚ฐ๊ตฌ ์ฒญํŒŒ๋กœ 47๊ธธ 100 ๐Ÿ“Œ</Text>
            </View>
            <View style={styles.categoryBar}>
                <CafeButton style={styles.category}/>
                <RestaurantButton style={styles.category}/>
                <DrinkButton style={styles.category}/>
                <EtcButton style={styles.category}/>
            </View>
            <View style={{flex: 0.4, margin: 15}}>
                <Text style={styles.randomText}>๋ฌด์ž‘์œ„ ์ถ”์ฒœ</Text>
            </View>
            <View style={styles.randomBar}>
                <ScrollView horizontal={false} style={styles.list}>
                    <View style={styles.stylegridView}>

                    <RandomImage/>
                    <RandomImage/>
                    <RandomImage/>
                    <RandomImage/>
                    <RandomImage/>
                    <RandomImage/>

                    </View>
                </ScrollView>
            </View>
        </View>
    );
}

const styles = StyleSheet.create({
    ์ดํ•˜ ์ƒ๋žต
});


export default MainScreen;

MainScreen์— ํ™ˆํ™”๋ฉด UI๋ฅผ ๋งŒ๋“ค์–ด๋’€๋Š”๋ฐ,

ํ™ˆ๊ณผ ๋ฉ”์ธ์„ ๊ฐ™์€ ํ™”๋ฉด์œผ๋กœ ํ—ท๊ฐˆ๋ ค์„œ ์ฝ”๋“œ๋ฅผ ์œ„์ฒ˜๋Ÿผ ์ž‘์„ฑํ•œ ๊ฒƒ ๊ฐ™๋‹ค.

 

์ด๋ ‡๊ฒŒ ํ™”๋ฉด์„ ๊ตฌ์„ฑํ•˜๋ฉด ํ™ˆํ™”๋ฉด์—์„œ

<Like, Cafe, Restaurant, Drink, Etc, Random>

ํŽ˜์ด์ง€๋กœ ํ™”๋ฉด์„ ์ด๋™ํ•  ์ˆ˜๋Š” ์žˆ์ง€๋งŒ

๋‚˜๋จธ์ง€ ํ•˜๋‹จํƒญ์ธ ์ง€๋„, ์ฝ”์Šค, ๋งˆ์ดํŽ˜์ด์ง€์˜ ๊ฐ ํ™”๋ฉด์—์„œ

๊ทธ ๋‚ด๋ถ€์˜ ๋‹ค๋ฅธ ํŽ˜์ด์ง€๋กœ ์ด๋™์ด ๋ถˆ๊ฐ€๋Šฅํ•˜๋‹ค.

 

์–ด์ฐจํ”ผ ๋‚˜์ค‘์— ํŒ€์›๋“ค๋ผ๋ฆฌ ๋งŒ๋“  ํ™”๋ฉด์„ ์„œ๋กœ ์—ฐ๊ฒฐํ•ด์•ผ ํ•˜๊ธฐ ๋•Œ๋ฌธ์—

๋‚ด๊ฐ€ ์ „์ฒด ๋„ค๋น„๊ฒŒ์ดํ„ฐ ๋ฐฉํ–ฅ์„ฑ์„ ์žก๊ณ 

๋‚ด ๊ฑธ ํŒ€์›๋“ค์—๊ฒŒ ์ „๋‹ฌํ•˜๋Š”๊ฒŒ ํ˜‘์—…์— ์ข‹์„ ๊ฒƒ ๊ฐ™์•„์„œ

App.js์™€ ์ „์ฒด์ ์ธ js ํŒŒ์ผ ๊ตฌ์กฐ๋“ค์„ ๋ฐ”๊ฟจ๋‹ค.

 

 

 

๋„ค๋น„๊ฒŒ์ด์…˜์€ ๋จธ๋ฆฟ์†์œผ๋กœ๋งŒ ๊ตฌ์ƒํ•˜๋‹ˆ ํ—ท๊ฐˆ๋ ค์„œ

์•„๋ž˜์ฒ˜๋Ÿผ ๊ตฌ์„ฑ๋„๋ฅผ ๊ทธ๋ ค์„œ App.js์— ๋ฐ˜์˜ํ–ˆ๋‹ค.

 

๊ฐ€๊ฒŒ ํŽ˜์ด์ง€๋“ค์€ ์ดํ›„์— ๋ฐฑ์—”๋“œ์™€ ์—ฐ๋™ํ•ด์•ผ ํ•ด์„œ

์ด์ „์— ๊ฐ๊ฐ <Cafe, Restaurant, Drink, Etc> ํŽ˜์ด์ง€๋ฅผ ๋งŒ๋“ค์–ด๋’€๋Š”๋ฐ

๊ทธ๊ฑธ ์‚ญ์ œํ•˜๊ณ  ๋นˆ Place ํŽ˜์ด์ง€ ํ•˜๋‚˜๋กœ ํ†ต์ผํ•ด์„œ ์ด๋™ํ•˜๊ฒŒ ํ–ˆ๋‹ค.

 

๋กœ๊ทธ์ธ ํ™”๋ฉด์€ ๋‹ค๋ฅธ ํŒ€์›์ด ์ˆ˜์ • ์ค‘์ด๋ผ

๋นˆ ํ™”๋ฉด์— ๋ฒ„ํŠผ ํ•˜๋‚˜๋ฅผ ๋‘๊ณ 

๋ฒ„ํŠผ์„ ํด๋ฆญํ•˜๋ฉด ๋ฉ”์ธ์œผ๋กœ ์ด๋™ํ•˜๋„๋ก ํ–ˆ๋‹ค.

 

MainScreen์— ์ž‘์„ฑํ–ˆ๋˜ ํ•˜๋‹จํƒญ ๋„ค๋น„๊ฒŒ์ดํ„ฐ๋ฅผ App.js๋กœ ํ•ฉ์น˜๊ณ ,

Main์—์„œ <Like, Cafe, Restaurant, Drink, Etc, Random>

๊ฐ ํŽ˜์ด์ง€๋กœ ์ด๋™ํ•  ์ˆ˜ ์žˆ๋„๋ก ์ž‘์„ฑํ–ˆ๋‹ค.

 

 

 

App.js (์ˆ˜์ • ํ›„)

import * as React from 'react';
import { NavigationContainer } from '@react-navigation/native';
import { createNativeStackNavigator } from '@react-navigation/native-stack';
import { createBottomTabNavigator } from '@react-navigation/bottom-tabs';
import Icon from 'react-native-vector-icons/MaterialIcons'

import Login from './android/screens/Login/Login'
import HomeScreen from './android/screens/HomeScreen';
import LikeScreen from './android/screens/LikeScreen'
import PlaceScreen from './android/screens/PlaceScreen';
import MapScreen from './android/screens/MapScreen';
import CourseScreen from './android/screens/CourseScreen';
import MyPageScreen from './android/screens/MyPageScreen';


const Stack = createNativeStackNavigator();
const Tab = createBottomTabNavigator();

function Main(){
    return (
        <Tab.Navigator initialRouteName="Home" screenOptions={{tabBarActiveTintColot: '#fd8c00'}}>
            <Tab.Screen name="Home" component={HomeScreen} options={{
            title: 'Home',
            tabBarIcon: ({color, size}) => (
                <Icon name="Home" color={color} size={size} />
            ),
            headerShown: false
            }}/>
            <Tab.Screen name="Map" component={MapScreen} options={{
            title: 'Map',
            tabBarIcon: ({color, size}) => (
                <Icon name="Place" color={color} size={size} />
            ),
            }}/>
            <Tab.Screen name="Course" component={CourseScreen} options={{
            title: 'Course',
            tabBarIcon: ({color, size}) => (
                <Icon name="Check" color={color} size={size} />
            ),
            }}/>
            <Tab.Screen name="My Page" component={MyPageScreen} options={{
            title: 'My Page',
            tabBarIcon: ({color, size}) => (
                <Icon name="Person" color={color} size={size} />
            ),
            }}/>
      </Tab.Navigator>
    );
}

export default function App() {
  return (
    <NavigationContainer>
      <Stack.Navigator initialRouteName="Login">
        <Stack.Screen
          name="Sign In"
          component={Login}
        />
        <Stack.Screen
          name="Main"
          component={Main}
          options={{headerShown: false}}
        />
        <Stack.Screen
          name="Like"
          component={LikeScreen}
        />
        <Stack.Screen
          name="Cafe"
          component={PlaceScreen}
        />
        <Stack.Screen
          name="Restaurant"
          component={PlaceScreen}
        />
        <Stack.Screen
          name="Drink"
          component={PlaceScreen}
        />
        <Stack.Screen
          name="Etc"
          component={PlaceScreen}
        />
        <Stack.Screen
          name="Random"
          component={PlaceScreen}
        />
      </Stack.Navigator>
    </NavigationContainer>
  );
}

 

HomeScreen.js (์ˆ˜์ • ํ›„)

import * as React from 'react';
import {Text, TextInput, View, Image, StyleSheet, ScrollView, TouchableOpacity} from 'react-native'
import { useNavigation } from '@react-navigation/native';

function LikeButton() {
    const navigation = useNavigation();
    return (
        <TouchableOpacity activeOpacity={0.8} onPress={() => navigation.push('Like')}>
          <Text style={{fontSize: 18, marginHorizontal: 10, marginVertical: 10}}>โค๏ธ</Text>
        </TouchableOpacity>
    );
}

function CafeButton() {
    const navigation = useNavigation();
    return (
        <TouchableOpacity activeOpacity={0.8} onPress={() => navigation.push('Cafe')}>
          <Text style={{fontSize: 40, marginHorizontal: 20, marginVertical: 10}}>๐Ÿง</Text>
          <Text style={{fontSize: 16, marginHorizontal: 30}}>Cafe</Text>
        </TouchableOpacity>
    );
}

function RestaurantButton() {
    const navigation = useNavigation();
    return (
        <TouchableOpacity activeOpacity={0.8} onPress={() => navigation.push('Restaurant')}>
          <Text style={{fontSize: 40, marginHorizontal: 23, marginVertical: 10}}>๐Ÿด</Text>
          <Text style={{fontSize: 16, marginHorizontal: 8}}>Restaurant</Text>
        </TouchableOpacity>
    );
}

function DrinkButton() {
    const navigation = useNavigation();
    return (
        <TouchableOpacity activeOpacity={0.8} onPress={() => navigation.push('Drink')}>
          <Text style={{fontSize: 40, marginHorizontal: 20, marginVertical: 10}}>๐Ÿบ</Text>
          <Text style={{fontSize: 16, marginHorizontal: 25}}>Drink</Text>
        </TouchableOpacity>
    );
}

function EtcButton() {
    const navigation = useNavigation();
    return (
        <TouchableOpacity activeOpacity={0.8} onPress={() => navigation.push('Etc')}>
          <Text style={{fontSize: 40, marginHorizontal: 20, marginVertical: 10}}>๐Ÿ‘€</Text>
          <Text style={{fontSize: 16, marginHorizontal: 33}}>Etc</Text>
        </TouchableOpacity>
    );
}

function RandomImage() {
    const navigation = useNavigation();
    return (
        <TouchableOpacity activeOpacity={0.8} onPress={() => navigation.push('Random')}>
          <Image style={styles.place} source={require('../assets/logo.png')}/>
          <View style={styles.info}>
            <Text>์ œ๋ชฉ</Text>
            <Text>์„ค๋ช…๋ธ”๋ผ๋ธ”๋ผ</Text>
          </View>
        </TouchableOpacity>
    );
}

function HomeScreen() {
    return(
        <View style={{flex: 1, flexDirection: 'column', backgroundColor: 'white'}}>
            <View style={styles.searchBar}>
                <Image style={styles.logoStyle} source={require('../assets/logo.png')}/>
                <TextInput style={styles.input}
                placeholder="#๊ฒ€์ƒ‰์–ด๋ฅผ ์ž…๋ ฅํ•˜์„ธ์š”."
                autoCapitalize="none" />
                <TouchableOpacity activeOpacity={0.8}>
                    <Text style={{fontSize: 18, marginHorizontal: 5}}>๐Ÿ”Ž</Text>
                </TouchableOpacity>
                <LikeButton style={styles.buttonStyle}/>
            </View>
            <View style={styles.locationBar}>
                <Text>์šฉ์‚ฐ๊ตฌ ์ฒญํŒŒ๋กœ 47๊ธธ 100 ๐Ÿ“Œ</Text>
            </View>
            <View style={styles.categoryBar}>
                <CafeButton style={styles.category}/>
                <RestaurantButton style={styles.category}/>
                <DrinkButton style={styles.category}/>
                <EtcButton style={styles.category}/>
            </View>
            <View style={{flex: 0.4, margin: 15}}>
                <Text style={styles.randomText}>๋ฌด์ž‘์œ„ ์ถ”์ฒœ</Text>
            </View>
            <View style={styles.randomBar}>
                <ScrollView horizontal={false} style={styles.list}>
                    <View style={styles.stylegridView}>

                    <RandomImage/>
                    <RandomImage/>
                    <RandomImage/>
                    <RandomImage/>
                    <RandomImage/>
                    <RandomImage/>

                    </View>
                </ScrollView>
            </View>
        </View>
    );
}

const styles = StyleSheet.create({
    ์ดํ•˜ ์ƒ๋žต
});


export default HomeScreen;

 

์ด์ „์— ๋น„ํ•ด ์ฝ”๋“œ๊ฐ€ ํ›จ์”ฌ ๊น”๋”ํ•ด์กŒ๊ณ ,

๋กœ๊ทธ์ธ-๋ฉ”์ธ, ๋ฉ”์ธ-๊ฐ ํŽ˜์ด์ง€๋กœ์˜ ์—ฐ๊ฒฐ๋„ ๊ฐ€๋Šฅํ•˜๋‹ค.

 

์™„์„ฑ ํ™”๋ฉด์€ ๋‹ค์Œ๊ณผ ๊ฐ™๋‹ค.

๋กœ๊ทธ์ธ - ๋ฉ”์ธ - Cafe